MINOR: stream_interface: Give stream_interface its own wait_list.
Instead of just using the conn_stream wait_list, give the stream_interface
its own. When the conn_stream will have its own buffers, the stream_interface
may have to wait on it.
diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h
index a102ac1..a9dca82 100644
--- a/include/proto/stream_interface.h
+++ b/include/proto/stream_interface.h
@@ -116,7 +116,7 @@
* any endpoint and only keeps its side which is expected to have already been
* set.
*/
-static inline void si_reset(struct stream_interface *si)
+static inline int si_reset(struct stream_interface *si)
{
si->err_type = SI_ET_NONE;
si->conn_retries = 0; /* used for logging too */
@@ -125,6 +125,14 @@
si->end = NULL;
si->state = si->prev_state = SI_ST_INI;
si->ops = &si_embedded_ops;
+ si->wait_list.task = tasklet_new();
+ if (!si->wait_list.task)
+ return -1;
+ si->wait_list.task->process = si_cs_io_cb;
+ si->wait_list.task->context = si;
+ si->wait_list.wait_reason = 0;
+ LIST_INIT(&si->wait_list.list);
+ return 0;
}
/* sets the current and previous state of a stream interface to <state>. This
diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
index 0c83759..eae1926 100644
--- a/include/types/stream_interface.h
+++ b/include/types/stream_interface.h
@@ -101,6 +101,7 @@
unsigned int err_type; /* first error detected, one of SI_ET_* */
int conn_retries; /* number of connect retries left */
unsigned int hcto; /* half-closed timeout (0 = unset) */
+ struct wait_list wait_list; /* We're in a wait list */
};
/* operations available on a stream-interface */
diff --git a/src/stream.c b/src/stream.c
index 9c427d4..bc0f1ac 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -192,7 +192,8 @@
vars_init(&s->vars_reqres, SCOPE_REQ);
/* this part should be common with other protocols */
- si_reset(&s->si[0]);
+ if (si_reset(&s->si[0]) < 0)
+ goto out_fail_alloc;
si_set_state(&s->si[0], SI_ST_EST);
s->si[0].hcto = sess->fe->timeout.clientfin;
@@ -211,7 +212,8 @@
/* pre-initialize the other side's stream interface to an INIT state. The
* callbacks will be initialized before attempting to connect.
*/
- si_reset(&s->si[1]);
+ if (si_reset(&s->si[1]) < 0)
+ goto out_fail_alloc_si1;
s->si[1].hcto = TICK_ETERNITY;
if (likely(sess->fe->options2 & PR_O2_INDEPSTR))
@@ -288,6 +290,9 @@
out_fail_accept:
flt_stream_release(s, 0);
task_free(t);
+ tasklet_free(s->si[1].wait_list.task);
+out_fail_alloc_si1:
+ tasklet_free(s->si[0].wait_list.task);
out_fail_alloc:
LIST_DEL(&s->list);
pool_free(pool_head_stream, s);
@@ -403,6 +408,8 @@
if (must_free_sess)
session_free(sess);
+ tasklet_free(s->si[0].wait_list.task);
+ tasklet_free(s->si[1].wait_list.task);
pool_free(pool_head_stream, s);
/* We may want to free the maximum amount of pools if the proxy is stopping */
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 290459a..4b5b760 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -651,7 +651,7 @@
int did_send = 0;
/* We're already waiting to be able to send, give up */
- if (cs->wait_list.wait_reason & SUB_CAN_SEND)
+ if (si->wait_list.wait_reason & SUB_CAN_SEND)
return NULL;
if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
@@ -660,7 +660,7 @@
if (conn->flags & CO_FL_HANDSHAKE) {
/* a handshake was requested */
/* Schedule ourself to be woken up once the handshake is done */
- conn->xprt->subscribe(conn, SUB_CAN_SEND, wl_set_waitcb(&cs->wait_list, si_cs_io_cb, cs));
+ conn->xprt->subscribe(conn, SUB_CAN_SEND, &si->wait_list);
return NULL;
}
@@ -740,7 +740,7 @@
}
/* We couldn't send all of our data, let the mux know we'd like to send more */
if (co_data(oc))
- conn->mux->subscribe(cs, SUB_CAN_SEND, wl_set_waitcb(&cs->wait_list, si_cs_io_cb, cs));
+ conn->mux->subscribe(cs, SUB_CAN_SEND, &si->wait_list);
wake_others:
/* Maybe somebody was waiting for this conn_stream, wake them */
@@ -759,7 +759,9 @@
struct task *si_cs_io_cb(struct task *t, void *ctx, unsigned short state)
{
- si_cs_send(ctx);
+ struct stream_interface *si = ctx;
+ if (!(si->wait_list.wait_reason & SUB_CAN_SEND))
+ si_cs_send(__objt_cs(si->end));
return (NULL);
}