diff --git a/src/mux_h2.c b/src/mux_h2.c index 6ec8d6c02..c4572d553 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3248,13 +3248,41 @@ static void h2_process_demux(struct h2c *h2c) TRACE_LEAVE(H2_EV_H2C_WAKE, h2c->conn); } +/* resume each h2s eligible for sending in list 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)) { @@ -3287,47 +3315,8 @@ static int h2_process_mux(struct h2c *h2c) * 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)) { @@ -3511,30 +3500,9 @@ static int h2_send(struct h2c *h2c) /* 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; + 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); - 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; - - /* 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);