MEDIUM: connection: make it possible for data->wake to return an error

Just like ->init(), ->wake() may now be used to return an error and
abort the connection. Currently this is not used but will be with
embryonic sessions.
This commit is contained in:
Willy Tarreau 2012-10-03 21:12:16 +02:00
parent 9e272bf95d
commit 2396c1c4a2
3 changed files with 15 additions and 7 deletions

View File

@ -180,12 +180,13 @@ struct xprt_ops {
* at the transport layer, which can be a connection opening/close, or any
* data movement. The <init> callback may be called by the connection handler
* at the end of a transport handshake, when it is about to transfer data and
* the data layer is not ready yet.
* the data layer is not ready yet. Both <wake> and <init> may abort a connection
* by returning < 0.
*/
struct data_cb {
void (*recv)(struct connection *conn); /* data-layer recv callback */
void (*send)(struct connection *conn); /* data-layer send callback */
void (*wake)(struct connection *conn); /* data-layer callback to report activity */
int (*wake)(struct connection *conn); /* data-layer callback to report activity */
int (*init)(struct connection *conn); /* data-layer initialization */
};

View File

@ -123,8 +123,14 @@ int conn_fd_handler(int fd)
return 0;
}
if ((conn->flags & CO_FL_WAKE_DATA) && ((conn->flags ^ flags) & CO_FL_CONN_STATE))
conn->data->wake(conn);
/* The wake callback may be used to process a critical error and abort the
* connection. If so, we don't want to go further as the connection will
* have been released and the FD destroyed.
*/
if ((conn->flags & CO_FL_WAKE_DATA) &&
((conn->flags ^ flags) & CO_FL_CONN_STATE) &&
conn->data->wake(conn) < 0)
return 0;
/* Last check, verify if the connection just established */
if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))

View File

@ -46,7 +46,7 @@ static void stream_int_chk_rcv_conn(struct stream_interface *si);
static void stream_int_chk_snd_conn(struct stream_interface *si);
static void si_conn_recv_cb(struct connection *conn);
static void si_conn_send_cb(struct connection *conn);
static void si_conn_wake_cb(struct connection *conn);
static int si_conn_wake_cb(struct connection *conn);
/* stream-interface operations for embedded tasks */
struct si_ops si_embedded_ops = {
@ -561,9 +561,9 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
* the update function in that it is designed to be called by lower layers after I/O
* events have been completed. It will also try to wake the associated task up if
* an important event requires special handling. It relies on the connection handler
* to commit any polling updates.
* to commit any polling updates. The function always returns 0.
*/
static void si_conn_wake_cb(struct connection *conn)
static int si_conn_wake_cb(struct connection *conn)
{
struct stream_interface *si = conn->owner;
@ -659,6 +659,7 @@ static void si_conn_wake_cb(struct connection *conn)
}
if (si->ib->flags & CF_READ_ACTIVITY)
si->ib->flags &= ~CF_READ_DONTWAIT;
return 0;
}
/*