mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-10-26 22:20:59 +01:00
MINOR: mt_list: Implement MT_LIST_POP_LOCKED()
Implement MT_LIST_POP_LOCKED(), that behaves as MT_LIST_POP() and removes the first element from the list, if any, but keeps it locked. This should be backported to 3.2, as it will be use in a bug fix in the stick tables that affects 3.2 too.
This commit is contained in:
parent
6316f958e3
commit
cf26745857
@ -245,6 +245,30 @@ mt_list_pop(l)
|
|||||||
#=========#
|
#=========#
|
||||||
|
|
||||||
|
|
||||||
|
mt_list_pop_locked(l)
|
||||||
|
Removes the list's first element, returns it locked. If the list was empty,
|
||||||
|
NULL is returned. A macro MT_LIST_POP_LOCKED() is provided for a
|
||||||
|
more convenient use; instead of returning the list element, it will return
|
||||||
|
the structure holding the element, taking care of preserving the NULL.
|
||||||
|
|
||||||
|
before:
|
||||||
|
+---+ +---+ +---+ +---+ +---+ +---+ +---+
|
||||||
|
#=>| L |<===>| A |<===>| B |<===>| C |<===>| D |<===>| E |<===>| F |<=#
|
||||||
|
# +---+ +---+ +---+ +---+ +---+ +---+ +---+ #
|
||||||
|
#=====================================================================#
|
||||||
|
|
||||||
|
after:
|
||||||
|
+---+ +---+ +---+ +---+ +---+ +---+
|
||||||
|
#=>| L |<===>| B |<===>| C |<===>| D |<===>| E |<===>| F |<=#
|
||||||
|
# +---+ +---+ +---+ +---+ +---+ +---+ #
|
||||||
|
#===========================================================#
|
||||||
|
|
||||||
|
+---+
|
||||||
|
# x| A |x #
|
||||||
|
# +---+ #
|
||||||
|
#=========#
|
||||||
|
|
||||||
|
|
||||||
_mt_list_lock_next(elt)
|
_mt_list_lock_next(elt)
|
||||||
Locks the link that starts at the next pointer of the designated element.
|
Locks the link that starts at the next pointer of the designated element.
|
||||||
The link is replaced by two locked pointers, and a pointer to the next
|
The link is replaced by two locked pointers, and a pointer to the next
|
||||||
|
|||||||
@ -128,6 +128,19 @@ struct mt_list {
|
|||||||
(_n ? MT_LIST_ELEM(_n, t, m) : NULL); \
|
(_n ? MT_LIST_ELEM(_n, t, m) : NULL); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* Returns a pointer of type <t> to the structure containing a member of type
|
||||||
|
* mt_list called <m> that comes from the first element in list <l>, that is
|
||||||
|
* atomically locked. If the list is empty, NULL is returned instead.
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* while ((conn = MT_LIST_POP_LOCKED(queue, struct conn *, list))) ...
|
||||||
|
*/
|
||||||
|
#define MT_LIST_POP_LOCKED(lh, t, m) \
|
||||||
|
({ \
|
||||||
|
struct mt_list *_n = mt_list_pop_locked(lh); \
|
||||||
|
(_n ? MT_LIST_ELEM(_n, t, m) : NULL); \
|
||||||
|
})
|
||||||
|
|
||||||
/* Iterates <item> through a list of items of type "typeof(*item)" which are
|
/* Iterates <item> through a list of items of type "typeof(*item)" which are
|
||||||
* linked via a "struct mt_list" member named <member>. A pointer to the head
|
* linked via a "struct mt_list" member named <member>. A pointer to the head
|
||||||
* of the list is passed in <list_head>.
|
* of the list is passed in <list_head>.
|
||||||
@ -633,10 +646,10 @@ static MT_INLINE long mt_list_delete(struct mt_list *el)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Removes the first element from the list <lh>, and returns it in detached
|
/* Removes the first element from the list <lh>, and returns it in locked
|
||||||
* form. If the list is already empty, NULL is returned instead.
|
* form. If the list is already empty, NULL is returned instead.
|
||||||
*/
|
*/
|
||||||
static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
|
static MT_INLINE struct mt_list *mt_list_pop_locked(struct mt_list *lh)
|
||||||
{
|
{
|
||||||
struct mt_list *n, *n2;
|
struct mt_list *n, *n2;
|
||||||
struct mt_list *p, *p2;
|
struct mt_list *p, *p2;
|
||||||
@ -687,15 +700,26 @@ static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
|
|||||||
n2->prev = lh;
|
n2->prev = lh;
|
||||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||||
|
|
||||||
n->prev = n->next = n;
|
|
||||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
|
||||||
|
|
||||||
/* return n */
|
/* return n */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Removes the first element from the list <lh>, and returns it in detached
|
||||||
|
* form. If the list is already empty, NULL is returned instead.
|
||||||
|
*/
|
||||||
|
static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
|
||||||
|
{
|
||||||
|
struct mt_list *ret = mt_list_pop_locked(lh);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
ret->prev = ret->next = ret;
|
||||||
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opens the list just after <lh> which usually is the list's head, but not
|
/* Opens the list just after <lh> which usually is the list's head, but not
|
||||||
* necessarily. The link between <lh> and its next element is cut and replaced
|
* necessarily. The link between <lh> and its next element is cut and replaced
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user