mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-04 19:19:33 +00:00
MINOR: event_hdl: pause/resume for subscriptions
While working on event handling from lua, the need for a pause/resume
function to temporarily disable a subscription was raised.
We solve this by introducing the EHDL_SUB_F_PAUSED flag for
subscriptions.
The flag is set via _pause() and cleared via _resume(), and it is
checked prior to notifying the subscription in publish function.
Pause and Resume functions are also available for via lookups for
identified subscriptions.
If 68e692da0
("MINOR: event_hdl: add event handler base api")
is being backported, then this commit should be backported with it.
This commit is contained in:
parent
b4b7320a6a
commit
f751a97a11
@ -206,12 +206,16 @@ struct event_hdl {
|
||||
void *private;
|
||||
};
|
||||
|
||||
/* flags for event_hdl_sub struct (32 bits) */
|
||||
#define EHDL_SUB_F_PAUSED 0x0001 /* subscription will temporarily ignore events */
|
||||
|
||||
/* list elem: subscription (handler subscribed to specific events)
|
||||
*/
|
||||
struct event_hdl_sub {
|
||||
struct mt_list mt_list;
|
||||
/* event type subscription */
|
||||
struct event_hdl_sub_type sub;
|
||||
uint32_t flags;
|
||||
/* event handler */
|
||||
struct event_hdl hdl;
|
||||
/* used to guarantee that END event will be delivered
|
||||
|
@ -301,6 +301,35 @@ int event_hdl_lookup_resubscribe(event_hdl_sub_list *sub_list,
|
||||
struct event_hdl_sub *event_hdl_lookup_take(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id);
|
||||
|
||||
/* pause an existing subscription <sub>
|
||||
* the subscription will no longer receive events (reversible)
|
||||
* This can be reverted thanks to _resume() function
|
||||
*/
|
||||
void event_hdl_pause(struct event_hdl_sub *sub);
|
||||
|
||||
/* resume an existing subscription <sub>
|
||||
* that was previously paused using _pause() function
|
||||
*/
|
||||
void event_hdl_resume(struct event_hdl_sub *sub);
|
||||
|
||||
/* Same as event_hdl_pause() for identified subscriptions:
|
||||
* use this function to pause the subscription <lookup_ip>
|
||||
* within <sub_list> list.
|
||||
* If <sub_list> is NULL, global subscription list will be used.
|
||||
* Returns 1 for SUCCESS and 0 if not found
|
||||
*/
|
||||
int event_hdl_lookup_pause(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id);
|
||||
|
||||
/* Same as event_hdl_resume() for identified subscriptions:
|
||||
* use this function to resume the subscription <lookup_ip>
|
||||
* within <sub_list> list.
|
||||
* If <sub_list> is NULL, global subscription list will be used.
|
||||
* Returns 1 for SUCCESS and 0 if not found
|
||||
*/
|
||||
int event_hdl_lookup_resume(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id);
|
||||
|
||||
/* ------ PUBLISHING FUNCTIONS ------ */
|
||||
|
||||
/* this macro is provided as an internal helper for EVENT_HDL_TRIGGER to automatically
|
||||
|
@ -444,6 +444,7 @@ struct event_hdl_sub *event_hdl_subscribe_ptr(event_hdl_sub_list *sub_list,
|
||||
/* assignments */
|
||||
new_sub->sub.family = e_type.family;
|
||||
new_sub->sub.subtype = e_type.subtype;
|
||||
new_sub->flags = 0;
|
||||
new_sub->hdl = hdl;
|
||||
|
||||
if (hdl.async) {
|
||||
@ -596,6 +597,38 @@ int event_hdl_resubscribe(struct event_hdl_sub *cur_sub, struct event_hdl_sub_ty
|
||||
return _event_hdl_resub_async(cur_sub, type);
|
||||
}
|
||||
|
||||
void _event_hdl_pause(struct event_hdl_sub *cur_sub)
|
||||
{
|
||||
cur_sub->flags |= EHDL_SUB_F_PAUSED;
|
||||
}
|
||||
|
||||
void event_hdl_pause(struct event_hdl_sub *cur_sub)
|
||||
{
|
||||
struct mt_list lock;
|
||||
|
||||
lock = MT_LIST_LOCK_ELT(&cur_sub->mt_list);
|
||||
if (lock.next != &cur_sub->mt_list)
|
||||
_event_hdl_pause(cur_sub);
|
||||
// else already removed
|
||||
MT_LIST_UNLOCK_ELT(&cur_sub->mt_list, lock);
|
||||
}
|
||||
|
||||
void _event_hdl_resume(struct event_hdl_sub *cur_sub)
|
||||
{
|
||||
cur_sub->flags &= ~EHDL_SUB_F_PAUSED;
|
||||
}
|
||||
|
||||
void event_hdl_resume(struct event_hdl_sub *cur_sub)
|
||||
{
|
||||
struct mt_list lock;
|
||||
|
||||
lock = MT_LIST_LOCK_ELT(&cur_sub->mt_list);
|
||||
if (lock.next != &cur_sub->mt_list)
|
||||
_event_hdl_resume(cur_sub);
|
||||
// else already removed
|
||||
MT_LIST_UNLOCK_ELT(&cur_sub->mt_list, lock);
|
||||
}
|
||||
|
||||
void event_hdl_unsubscribe(struct event_hdl_sub *del_sub)
|
||||
{
|
||||
_event_hdl_unsubscribe_async(del_sub);
|
||||
@ -660,6 +693,48 @@ int event_hdl_lookup_resubscribe(event_hdl_sub_list *sub_list,
|
||||
return status;
|
||||
}
|
||||
|
||||
int event_hdl_lookup_pause(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id)
|
||||
{
|
||||
struct event_hdl_sub *cur_sub = NULL;
|
||||
struct mt_list *elt1, elt2;
|
||||
int found = 0;
|
||||
|
||||
if (!sub_list)
|
||||
sub_list = &global_event_hdl_sub_list; /* fall back to global list */
|
||||
|
||||
mt_list_for_each_entry_safe(cur_sub, &sub_list->head, mt_list, elt1, elt2) {
|
||||
if (lookup_id == cur_sub->hdl.id) {
|
||||
/* we found matching registered hdl */
|
||||
_event_hdl_pause(cur_sub);
|
||||
found = 1;
|
||||
break; /* id is unique, stop searching */
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int event_hdl_lookup_resume(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id)
|
||||
{
|
||||
struct event_hdl_sub *cur_sub = NULL;
|
||||
struct mt_list *elt1, elt2;
|
||||
int found = 0;
|
||||
|
||||
if (!sub_list)
|
||||
sub_list = &global_event_hdl_sub_list; /* fall back to global list */
|
||||
|
||||
mt_list_for_each_entry_safe(cur_sub, &sub_list->head, mt_list, elt1, elt2) {
|
||||
if (lookup_id == cur_sub->hdl.id) {
|
||||
/* we found matching registered hdl */
|
||||
_event_hdl_resume(cur_sub);
|
||||
found = 1;
|
||||
break; /* id is unique, stop searching */
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
struct event_hdl_sub *event_hdl_lookup_take(event_hdl_sub_list *sub_list,
|
||||
uint64_t lookup_id)
|
||||
{
|
||||
@ -694,9 +769,10 @@ static int _event_hdl_publish(event_hdl_sub_list *sub_list, struct event_hdl_sub
|
||||
int error = 0;
|
||||
|
||||
mt_list_for_each_entry_safe(cur_sub, &sub_list->head, mt_list, elt1, elt2) {
|
||||
/* notify each function that has subscribed to sub_family.type */
|
||||
/* notify each function that has subscribed to sub_family.type, unless paused */
|
||||
if ((cur_sub->sub.family == e_type.family) &&
|
||||
((cur_sub->sub.subtype & e_type.subtype) == e_type.subtype)) {
|
||||
((cur_sub->sub.subtype & e_type.subtype) == e_type.subtype) &&
|
||||
!(cur_sub->flags & EHDL_SUB_F_PAUSED)) {
|
||||
/* hdl should be notified */
|
||||
if (!cur_sub->hdl.async) {
|
||||
/* sync mode: simply call cb pointer
|
||||
|
Loading…
Reference in New Issue
Block a user