TRACE_LEAVE(H2_EV_H2C_WAKE, h2c->conn);
}
+/* resume each h2s eligible for sending in list head <head> */
+static void h2_resume_each_sending_h2s(struct h2c *h2c, struct list *head)
+{
+ struct h2s *h2s, *h2s_back;
+
+ TRACE_ENTER(H2_EV_H2C_SEND|H2_EV_H2S_WAKE, h2c->conn);
+
+ list_for_each_entry_safe(h2s, h2s_back, head, list) {
+ if (h2c->mws <= 0 ||
+ h2c->flags & H2_CF_MUX_BLOCK_ANY ||
+ h2c->st0 >= H2_CS_ERROR)
+ break;
+
+ h2s->flags &= ~H2_SF_BLK_ANY;
+ /* For some reason, the upper layer failed to subscribe again,
+ * so remove it from the send_list
+ */
+ if (!h2s->send_wait) {
+ LIST_DEL_INIT(&h2s->list);
+ continue;
+ }
+
+ h2s->send_wait->events &= ~SUB_RETRY_SEND;
+ LIST_ADDQ(&h2c->sending_list, &h2s->sending_list);
+ tasklet_wakeup(h2s->send_wait->tasklet);
+ }
+
+ TRACE_LEAVE(H2_EV_H2C_SEND|H2_EV_H2S_WAKE, h2c->conn);
+}
+
/* process Tx frames from streams to be multiplexed. Returns > 0 if it reached
* the end.
*/
static int h2_process_mux(struct h2c *h2c)
{
- struct h2s *h2s, *h2s_back;
-
TRACE_ENTER(H2_EV_H2C_WAKE, h2c->conn);
if (unlikely(h2c->st0 < H2_CS_FRAME_H)) {
* waiting there were already elected for immediate emission but were
* blocked just on this.
*/
-
- list_for_each_entry_safe(h2s, h2s_back, &h2c->fctl_list, list) {
- if (h2c->mws <= 0 || h2c->flags & H2_CF_MUX_BLOCK_ANY ||
- h2c->st0 >= H2_CS_ERROR)
- break;
-
- if (LIST_ADDED(&h2s->sending_list))
- continue;
-
- h2s->flags &= ~H2_SF_BLK_ANY;
- /* For some reason, the upper layer failed to subsribe again,
- * so remove it from the send_list
- */
- if (!h2s->send_wait) {
- LIST_DEL_INIT(&h2s->list);
- continue;
- }
- h2s->send_wait->events &= ~SUB_RETRY_SEND;
- LIST_ADDQ(&h2c->sending_list, &h2s->sending_list);
- tasklet_wakeup(h2s->send_wait->tasklet);
- }
-
- list_for_each_entry_safe(h2s, h2s_back, &h2c->send_list, list) {
- if (h2c->st0 >= H2_CS_ERROR || h2c->flags & H2_CF_MUX_BLOCK_ANY)
- break;
-
- if (LIST_ADDED(&h2s->sending_list))
- continue;
-
- /* For some reason, the upper layer failed to subsribe again,
- * so remove it from the send_list
- */
- if (!h2s->send_wait) {
- LIST_DEL_INIT(&h2s->list);
- continue;
- }
- h2s->flags &= ~H2_SF_BLK_ANY;
- h2s->send_wait->events &= ~SUB_RETRY_SEND;
- LIST_ADDQ(&h2c->sending_list, &h2s->sending_list);
- tasklet_wakeup(h2s->send_wait->tasklet);
- }
+ h2_resume_each_sending_h2s(h2c, &h2c->fctl_list);
+ h2_resume_each_sending_h2s(h2c, &h2c->send_list);
fail:
if (unlikely(h2c->st0 >= H2_CS_ERROR)) {
/* We're not full anymore, so we can wake any task that are waiting
* for us.
*/
- if (!(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM)) && h2c->st0 >= H2_CS_FRAME_H) {
- struct h2s *h2s;
-
- list_for_each_entry(h2s, &h2c->send_list, list) {
- if (h2c->st0 >= H2_CS_ERROR || h2c->flags & H2_CF_MUX_BLOCK_ANY)
- break;
-
- if (LIST_ADDED(&h2s->sending_list))
- continue;
+ if (!(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM)) && h2c->st0 >= H2_CS_FRAME_H)
+ h2_resume_each_sending_h2s(h2c, &h2c->send_list);
- /* For some reason, the upper layer failed to subsribe again,
- * so remove it from the send_list
- */
- if (!h2s->send_wait) {
- LIST_DEL_INIT(&h2s->list);
- continue;
- }
- h2s->flags &= ~H2_SF_BLK_ANY;
- h2s->send_wait->events &= ~SUB_RETRY_SEND;
- TRACE_DEVEL("waking up pending stream", H2_EV_H2C_SEND|H2_EV_H2S_WAKE, h2c->conn, h2s);
- tasklet_wakeup(h2s->send_wait->tasklet);
- LIST_ADDQ(&h2c->sending_list, &h2s->sending_list);
- }
- }
/* We're done, no more to send */
if (!br_data(h2c->mbuf)) {
TRACE_DEVEL("leaving with everything sent", H2_EV_H2C_SEND, h2c->conn);