diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index 1fe25f59d..d9a32e09a 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -226,7 +226,7 @@ struct li_per_thread { struct listener { enum obj_type obj_type; /* object type = OBJ_TYPE_LISTENER */ enum li_state state; /* state: NEW, INIT, ASSIGNED, LISTEN, READY, FULL */ - /* 2-byte hole here */ + uint16_t flags; /* listener flags: LI_F_* */ int luid; /* listener universally unique ID, used for SNMP */ int nbconn; /* current number of connections on this listener */ unsigned int thr_idx; /* thread indexes for queue distribution : (t2<<16)+t1 */ @@ -251,6 +251,9 @@ struct listener { EXTRA_COUNTERS(extra_counters); }; +/* listener flags (16 bits) */ +#define LI_F_FINALIZED 0x0001 /* listener made it to the READY||LIMITED||FULL state at least once, may be suspended/resumed safely */ + /* Descriptor for a "bind" keyword. The ->parse() function returns 0 in case of * success, or a combination of ERR_* flags if an error is encountered. The * function pointer can be NULL if not implemented. The function also has an diff --git a/src/listener.c b/src/listener.c index 08dd5ecad..25b22e13c 100644 --- a/src/listener.c +++ b/src/listener.c @@ -288,6 +288,7 @@ void listener_set_state(struct listener *l, enum li_state st) case LI_LIMITED: BUG_ON(l->rx.fd == -1); _HA_ATOMIC_INC(&px->li_ready); + l->flags |= LI_F_FINALIZED; break; } } @@ -477,7 +478,7 @@ int pause_listener(struct listener *l, int lpx, int lli) if (!lli) HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); - if (l->state <= LI_PAUSED) + if (!(l->flags & LI_F_FINALIZED) || l->state <= LI_PAUSED) goto end; if (l->rx.proto->suspend) @@ -535,7 +536,7 @@ int resume_listener(struct listener *l, int lpx, int lli) if (MT_LIST_INLIST(&l->wait_queue)) goto end; - if (l->state == LI_READY) + if (!(l->flags & LI_F_FINALIZED) || l->state == LI_READY) goto end; if (l->rx.proto->resume)