*/
void listener_release(struct listener *l);
+/* default function used to unbind a listener. This is for use by standard
+ * protocols working on top of accepted sockets. The receiver's rx_unbind()
+ * will automatically be used after the listener is disabled if the socket is
+ * still bound. This must be used under the listener's lock.
+ */
+void default_unbind_listener(struct listener *listener);
/*
* Registers the bind keyword list <kwl> as a list of valid keywords for next
* parsing sessions.
int (*listen)(struct listener *l, char *errmsg, int errlen); /* start a listener */
void (*enable)(struct listener *l); /* enable receipt of new connections */
void (*disable)(struct listener *l); /* disable receipt of new connections */
+ void (*unbind)(struct listener *l); /* unbind the listener and possibly its receiver */
/* functions acting on the receiver */
void (*rx_enable)(struct receiver *rx); /* enable receiving on the receiver */
}
}
-/* This function closes the listening socket for the specified listener,
- * provided that it's already in a listening state. The listener enters the
- * 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, according to what is provided at the receiver
- * level. Must be called with the lock held.
+
+/* default function used to unbind a listener. This is for use by standard
+ * protocols working on top of accepted sockets. The receiver's rx_unbind()
+ * will automatically be used after the listener is disabled if the socket is
+ * still bound. This must be used under the listener's lock.
*/
-void do_unbind_listener(struct listener *listener)
+void default_unbind_listener(struct listener *listener)
{
- MT_LIST_DEL(&listener->wait_queue);
-
if (listener->state <= LI_ASSIGNED)
goto out_close;
out_close:
if (listener->rx.flags & RX_F_BOUND)
listener->rx.proto->rx_unbind(&listener->rx);
+}
+
+/* This function closes the listening socket for the specified listener,
+ * provided that it's already in a listening state. The protocol's unbind()
+ * is called to put the listener into LI_ASSIGNED or LI_LISTEN and handle
+ * the unbinding tasks. The listener enters then the LI_ASSIGNED state if
+ * the receiver is unbound. Must be called with the lock held.
+ */
+void do_unbind_listener(struct listener *listener)
+{
+ MT_LIST_DEL(&listener->wait_queue);
+
+ if (listener->rx.proto->unbind)
+ listener->rx.proto->unbind(listener);
/* we may have to downgrade the listener if the rx was closed */
if (!(listener->rx.flags & RX_F_BOUND) && listener->state > LI_ASSIGNED)
.listen = sockpair_bind_listener,
.enable = sockpair_enable_listener,
.disable = sockpair_disable_listener,
+ .unbind = default_unbind_listener,
.rx_unbind = sock_unbind,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.listen = tcp_bind_listener,
.enable = tcp_enable_listener,
.disable = tcp_disable_listener,
+ .unbind = default_unbind_listener,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_unbind = sock_unbind,
.listen = tcp_bind_listener,
.enable = tcp_enable_listener,
.disable = tcp_disable_listener,
+ .unbind = default_unbind_listener,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_unbind = sock_unbind,
.listen = udp_bind_listener,
.enable = udp_enable_listener,
.disable = udp_disable_listener,
+ .unbind = default_unbind_listener,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_unbind = sock_unbind,
.listen = udp_bind_listener,
.enable = udp_enable_listener,
.disable = udp_disable_listener,
+ .unbind = default_unbind_listener,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_unbind = sock_unbind,
.listen = uxst_bind_listener,
.enable = uxst_enable_listener,
.disable = uxst_disable_listener,
+ .unbind = default_unbind_listener,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_unbind = sock_unbind,