mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-19 12:16:59 +00:00
MEDIUM: receivers: add an rx_unbind() method in the protocols
This is used as a generic way to unbind a receiver at the end of do_unbind_listener(). This allows to considerably simplify that function since we can now let the protocol perform the cleanup. The generic code was moved to sock.c, along with the conditional rx_disable() call. Now the code also supports that the ->disable() function of the protocol which acts on the listener performs the close itself and adjusts the RX_F_BUOND flag accordingly.
This commit is contained in:
parent
18c20d28d7
commit
f58b8db47b
@ -95,6 +95,7 @@ struct protocol {
|
||||
/* functions acting on the receiver */
|
||||
void (*rx_enable)(struct receiver *rx); /* enable receiving on the receiver */
|
||||
void (*rx_disable)(struct receiver *rx); /* disable receiving on the receiver */
|
||||
void (*rx_unbind)(struct receiver *rx); /* unbind the receiver, most often closing the FD */
|
||||
int (*rx_suspend)(struct receiver *rx); /* temporarily suspend this receiver for a soft restart */
|
||||
int (*rx_resume)(struct receiver *rx); /* try to resume a temporarily suspended receiver */
|
||||
|
||||
|
@ -35,6 +35,7 @@ extern struct xfer_sock_list *xfer_sock_list;
|
||||
int sock_create_server_socket(struct connection *conn);
|
||||
void sock_enable(struct receiver *rx);
|
||||
void sock_disable(struct receiver *rx);
|
||||
void sock_unbind(struct receiver *rx);
|
||||
int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int sock_get_old_sockets(const char *unixsocket);
|
||||
|
@ -543,7 +543,8 @@ void dequeue_proxy_listeners(struct proxy *px)
|
||||
* LI_ASSIGNED state, except if the FD is not closed, in which case it may
|
||||
* remain in LI_LISTEN. Depending on the process' status (master or worker),
|
||||
* the listener's bind options and the receiver's origin, it may or may not
|
||||
* close the receiver's FD. Must be called with the lock held.
|
||||
* close the receiver's FD, according to what is provided at the receiver
|
||||
* level. Must be called with the lock held.
|
||||
*/
|
||||
void do_unbind_listener(struct listener *listener)
|
||||
{
|
||||
@ -557,40 +558,18 @@ void do_unbind_listener(struct listener *listener)
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if (listener->state >= LI_PAUSED) {
|
||||
if (listener->state >= LI_READY) {
|
||||
listener->rx.proto->disable(listener);
|
||||
if (listener->state >= LI_READY) {
|
||||
listener->rx.proto->disable(listener);
|
||||
if (listener->rx.flags & RX_F_BOUND)
|
||||
listener_set_state(listener, LI_LISTEN);
|
||||
}
|
||||
listener->rx.proto->rx_disable(&listener->rx);
|
||||
}
|
||||
|
||||
out_close:
|
||||
/* There are a number of situations where we prefer to keep the FD and
|
||||
* not to close it (unless we're stopping, of course):
|
||||
* - worker process unbinding from a worker's FD with socket transfer enabled => keep
|
||||
* - master process unbinding from a master's inherited FD => keep
|
||||
* - master process unbinding from a master's FD => close
|
||||
* - master process unbinding from a worker's FD => close
|
||||
* - worker process unbinding from a master's FD => close
|
||||
* - worker process unbinding from a worker's FD => close
|
||||
*/
|
||||
if (listener->rx.flags & RX_F_BOUND)
|
||||
listener->rx.proto->rx_unbind(&listener->rx);
|
||||
|
||||
if (!stopping && !master &&
|
||||
!(listener->rx.flags & RX_F_MWORKER) &&
|
||||
(global.tune.options & GTUNE_SOCKET_TRANSFER))
|
||||
return;
|
||||
|
||||
if (!stopping && master &&
|
||||
listener->rx.flags & RX_F_MWORKER &&
|
||||
listener->rx.flags & RX_F_INHERITED)
|
||||
return;
|
||||
|
||||
listener->rx.flags &= ~RX_F_BOUND;
|
||||
if (listener->rx.fd != -1)
|
||||
fd_delete(listener->rx.fd);
|
||||
listener->rx.fd = -1;
|
||||
if (listener->state > LI_ASSIGNED)
|
||||
/* we may have to downgrade the listener if the rx was closed */
|
||||
if (!(listener->rx.flags & RX_F_BOUND) && listener->state > LI_ASSIGNED)
|
||||
listener_set_state(listener, LI_ASSIGNED);
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ static struct protocol proto_sockpair = {
|
||||
.listen = sockpair_bind_listener,
|
||||
.enable = sockpair_enable_listener,
|
||||
.disable = sockpair_disable_listener,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.accept = &listener_accept,
|
||||
|
@ -66,6 +66,7 @@ static struct protocol proto_tcpv4 = {
|
||||
.disable = tcp_disable_listener,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_suspend = tcp_suspend_receiver,
|
||||
.rx_resume = tcp_resume_receiver,
|
||||
.accept = &listener_accept,
|
||||
@ -90,6 +91,7 @@ static struct protocol proto_tcpv6 = {
|
||||
.disable = tcp_disable_listener,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_suspend = tcp_suspend_receiver,
|
||||
.rx_resume = tcp_resume_receiver,
|
||||
.accept = &listener_accept,
|
||||
|
@ -62,6 +62,7 @@ static struct protocol proto_udp4 = {
|
||||
.disable = udp_disable_listener,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_suspend = udp_suspend_receiver,
|
||||
.rx_resume = udp_resume_receiver,
|
||||
.receivers = LIST_HEAD_INIT(proto_udp4.receivers),
|
||||
@ -84,6 +85,7 @@ static struct protocol proto_udp6 = {
|
||||
.disable = udp_disable_listener,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_suspend = udp_suspend_receiver,
|
||||
.rx_resume = udp_resume_receiver,
|
||||
.receivers = LIST_HEAD_INIT(proto_udp6.receivers),
|
||||
|
@ -61,6 +61,7 @@ static struct protocol proto_unix = {
|
||||
.disable = uxst_disable_listener,
|
||||
.rx_enable = sock_enable,
|
||||
.rx_disable = sock_disable,
|
||||
.rx_unbind = sock_unbind,
|
||||
.rx_suspend = uxst_suspend_receiver,
|
||||
.accept = &listener_accept,
|
||||
.connect = &uxst_connect_server,
|
||||
|
31
src/sock.c
31
src/sock.c
@ -73,6 +73,37 @@ void sock_disable(struct receiver *rx)
|
||||
fd_stop_recv(rx->fd);
|
||||
}
|
||||
|
||||
/* stops, unbinds and possibly closes the FD associated with receiver rx */
|
||||
void sock_unbind(struct receiver *rx)
|
||||
{
|
||||
/* There are a number of situations where we prefer to keep the FD and
|
||||
* not to close it (unless we're stopping, of course):
|
||||
* - worker process unbinding from a worker's FD with socket transfer enabled => keep
|
||||
* - master process unbinding from a master's inherited FD => keep
|
||||
* - master process unbinding from a master's FD => close
|
||||
* - master process unbinding from a worker's FD => close
|
||||
* - worker process unbinding from a master's FD => close
|
||||
* - worker process unbinding from a worker's FD => close
|
||||
*/
|
||||
if (rx->flags & RX_F_BOUND)
|
||||
rx->proto->rx_disable(rx);
|
||||
|
||||
if (!stopping && !master &&
|
||||
!(rx->flags & RX_F_MWORKER) &&
|
||||
(global.tune.options & GTUNE_SOCKET_TRANSFER))
|
||||
return;
|
||||
|
||||
if (!stopping && master &&
|
||||
rx->flags & RX_F_MWORKER &&
|
||||
rx->flags & RX_F_INHERITED)
|
||||
return;
|
||||
|
||||
rx->flags &= ~RX_F_BOUND;
|
||||
if (rx->fd != -1)
|
||||
fd_delete(rx->fd);
|
||||
rx->fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the source address for the socket <fd>, with <dir> indicating
|
||||
* if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
|
||||
|
Loading…
Reference in New Issue
Block a user