mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-12 16:37:20 +00: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 */
|
||||
};
|
||||
|
||||
/* 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. */
|
||||
struct wordlist {
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user