mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: list: define a watcher type
Define a new watcher type into list module. This type is similar to bref and can be used to register an element which is currently tracking a dynamic target. Contrary to bref, if the target is freed, every watcher element are updated to point to a next valid entry or NULL. This type will simplify handling of dynamic servers deletion, in particular while stats dump are performed. This patch is not a bug-fix. However, it is mandatory to fix a race condition in dynamic servers. Thus, it should be backported along the next commit up to 2.6.
This commit is contained in:
parent
2199179461
commit
eafa8a32bb
@ -57,6 +57,17 @@ struct bref {
|
|||||||
struct list *ref; /* pointer to the target's list entry */
|
struct list *ref; /* pointer to the target's list entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Similar to bref. Used to reference an element which is tracking a dynamic
|
||||||
|
* target. The main advantage over bref is that when target is freed, each
|
||||||
|
* elements pointers are automatically updated to the next entry or NULL if
|
||||||
|
* target was the last one.
|
||||||
|
*/
|
||||||
|
struct watcher {
|
||||||
|
struct mt_list el; /* attach point into target list */
|
||||||
|
void **pptr; /* pointer to element which points to target */
|
||||||
|
size_t off; /* offset into target type for mtlist storage of watcher */
|
||||||
|
};
|
||||||
|
|
||||||
/* a word list is a generic list with a pointer to a string in each element. */
|
/* a word list is a generic list with a pointer to a string in each element. */
|
||||||
struct wordlist {
|
struct wordlist {
|
||||||
struct list list;
|
struct list list;
|
||||||
|
@ -260,4 +260,46 @@ static __inline struct mt_list *list_to_mt_list(struct list *list)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Init a <w> watcher entry to track targets. <pptr> is the pointer to the
|
||||||
|
* target pointer which will be updated via watcher_attach/detach operations.
|
||||||
|
* <attach_off> is the offset to access the target mt_list attach point for the
|
||||||
|
* watcher entry.
|
||||||
|
*/
|
||||||
|
static __inline void watcher_init(struct watcher *w, void *pptr, size_t attach_off)
|
||||||
|
{
|
||||||
|
MT_LIST_INIT(&w->el);
|
||||||
|
w->pptr = pptr;
|
||||||
|
w->off = attach_off;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tracks <target> via <w> watcher. Invalid if <w> is already attached. */
|
||||||
|
static __inline void watcher_attach(struct watcher *w, void *target)
|
||||||
|
{
|
||||||
|
struct mt_list *list = target + w->off;
|
||||||
|
|
||||||
|
BUG_ON_HOT(MT_LIST_INLIST(&w->el));
|
||||||
|
|
||||||
|
*w->pptr = target;
|
||||||
|
if (target)
|
||||||
|
MT_LIST_APPEND(list, &w->el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Untracks target via <w> watcher. Invalid if <w> is not attached first. */
|
||||||
|
static __inline void watcher_detach(struct watcher *w)
|
||||||
|
{
|
||||||
|
BUG_ON_HOT(!MT_LIST_INLIST(&w->el));
|
||||||
|
*w->pptr = NULL;
|
||||||
|
MT_LIST_DELETE(&w->el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Equivalent to a detach then attach on <target> via <w> watcher. Returns
|
||||||
|
* <target> as a convenience to use this function as increment in a for-loop.
|
||||||
|
*/
|
||||||
|
static __inline void *watcher_next(struct watcher *w, void *target)
|
||||||
|
{
|
||||||
|
watcher_detach(w);
|
||||||
|
watcher_attach(w, target);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _HAPROXY_LIST_H */
|
#endif /* _HAPROXY_LIST_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user