]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: provide a generic data layer wakeup callback
authorWilly Tarreau <w@1wt.eu>
Tue, 2 Oct 2012 18:07:22 +0000 (20:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 4 Oct 2012 20:26:10 +0000 (22:26 +0200)
Instead of calling conn_notify_si() from the connection handler, we
now call data->wake(), which will allow us to use a different callback
with health checks.

Note that we still rely on a flag in order to decide whether or not
to call this function. The reason is that with embryonic sessions,
the callback is already initialized to si_conn_cb without the flag,
and we can't call the SI notify function in the leave path before
the stream interface is initialized.

This issue should be addressed by involving a different data_cb for
embryonic sessions and for stream interfaces, that would be changed
during session_complete() for the final data_cb.

include/proto/stream_interface.h
include/types/connection.h
src/connection.c
src/session.c
src/stream_interface.c

index 3472b990a0b9884f7ad577b50dc05c117ee8fba8..bf03f6e1c036746d0aa3915a6332d7431a4d74e8 100644 (file)
@@ -36,11 +36,8 @@ int stream_int_check_timeouts(struct stream_interface *si);
 void stream_int_report_error(struct stream_interface *si);
 void stream_int_retnclose(struct stream_interface *si, const struct chunk *msg);
 int conn_si_send_proxy(struct connection *conn, unsigned int flag);
-void conn_notify_si(struct connection *conn);
 int stream_int_shutr(struct stream_interface *si);
 int stream_int_shutw(struct stream_interface *si);
-void si_conn_recv_cb(struct connection *conn);
-void si_conn_send_cb(struct connection *conn);
 void stream_sock_read0(struct stream_interface *si);
 
 extern struct si_ops si_embedded_ops;
@@ -135,7 +132,7 @@ static inline int si_connect(struct stream_interface *si)
                si->conn.flags |= CO_FL_SI_SEND_PROXY;
 
        /* we need to be notified about connection establishment */
-       si->conn.flags |= CO_FL_NOTIFY_SI;
+       si->conn.flags |= CO_FL_WAKE_DATA;
 
        /* we're in the process of establishing a connection */
        si->state = SI_ST_CON;
index c289efa9a77f8407152d1336988d2a7a4fe03261..c8858c36f9a1109dfe119ae43621a9342e8edfde 100644 (file)
@@ -76,7 +76,7 @@ enum {
        CO_FL_WAIT_L4_CONN  = 0x00000004,  /* waiting for L4 to be connected */
        CO_FL_WAIT_L6_CONN  = 0x00000008,  /* waiting for L6 to be connected (eg: SSL) */
 
-       CO_FL_NOTIFY_SI     = 0x00000010,  /* notify stream interface about changes */
+       CO_FL_WAKE_DATA     = 0x00000010,  /* wake-up data layer upon activity at the transport layer */
 
        /* flags below are used for connection handshakes */
        CO_FL_SI_SEND_PROXY = 0x00000020,  /* send a valid PROXY protocol header */
@@ -172,11 +172,14 @@ struct xprt_ops {
 /* data_cb describes the data layer's recv and send callbacks which are called
  * when I/O activity was detected after the transport layer is ready. These
  * callbacks are supposed to make use of the xprt_ops above to exchange data
- * from/to buffers and pipes.
+ * from/to buffers and pipes. The <wake> callback is used to report activity
+ * at the transport layer, which can be a connection opening/close, or any
+ * data movement.
  */
 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 */
 };
 
 /* a target describes what is on the remote side of the connection. */
index 07225e9d3be85dc8ad4d027e50aa04f8814b3060..007d3b1bed754e2b31e356b6671c2eec689a9a32 100644 (file)
@@ -110,8 +110,8 @@ int conn_fd_handler(int fd)
                return 0;
        }
 
-       if (conn->flags & CO_FL_NOTIFY_SI)
-               conn_notify_si(conn);
+       if (conn->flags & CO_FL_WAKE_DATA)
+               conn->data->wake(conn);
 
        /* 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))))
index 975176c3e7c38ae9a8513ccb06342d9656804b01..b697599cd8eb585ec9ee7b8b3aef02ba63f1baee 100644 (file)
@@ -462,7 +462,7 @@ int session_complete(struct session *s)
        }
 
        /* we want the connection handler to notify the stream interface about updates. */
-       s->si[0].conn.flags |= CO_FL_NOTIFY_SI;
+       s->si[0].conn.flags |= CO_FL_WAKE_DATA;
 
        /* it is important not to call the wakeup function directly but to
         * pass through task_wakeup(), because this one knows how to apply
index faedddedfb934bdce03c9c3f8a2c3c169073e779..83e085920cd6f92e3205894b8093da99a2fa08d2 100644 (file)
@@ -44,6 +44,9 @@ static void stream_int_chk_snd(struct stream_interface *si);
 static void stream_int_update_conn(struct stream_interface *si);
 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);
 
 /* stream-interface operations for embedded tasks */
 struct si_ops si_embedded_ops = {
@@ -69,6 +72,7 @@ struct si_ops si_conn_ops = {
 struct data_cb si_conn_cb = {
        .recv    = si_conn_recv_cb,
        .send    = si_conn_send_cb,
+       .wake    = si_conn_wake_cb,
 };
 
 /*
@@ -554,12 +558,12 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
 }
 
 /* Callback to be used by connection I/O handlers upon completion. It differs from
- * the function below in that it is designed to be called by lower layers after I/O
+ * 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.
  */
-void conn_notify_si(struct connection *conn)
+static void si_conn_wake_cb(struct connection *conn)
 {
        struct stream_interface *si = conn->owner;
 
@@ -938,7 +942,7 @@ static void stream_int_chk_snd_conn(struct stream_interface *si)
  * into the buffer from the connection. It iterates over the transport layer's
  * rcv_buf function.
  */
-void si_conn_recv_cb(struct connection *conn)
+static void si_conn_recv_cb(struct connection *conn)
 {
        struct stream_interface *si = conn->owner;
        struct channel *b = si->ib;
@@ -1152,7 +1156,7 @@ void si_conn_recv_cb(struct connection *conn)
  * from the buffer to the connection. It iterates over the transport layer's
  * snd_buf function.
  */
-void si_conn_send_cb(struct connection *conn)
+static void si_conn_send_cb(struct connection *conn)
 {
        struct stream_interface *si = conn->owner;
        struct channel *b = si->ob;