In case any stream was waiting for the handshake after receiving early data,
we have to wake all of them. Do so by making the mux responsible for
removing the CO_FL_EARLY_DATA flag after all of them are woken up, instead
of doing it in si_cs_wake_cb(), which would then only work for the first one.
This makes wait_for_handshake work with HTTP/2.
{
struct h2c *h2c = conn->mux_ctx;
+ /*
+ * If we received early data, try to wake any stream, just in case
+ * at least one of them was waiting for the handshake
+ */
+ if ((conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_EARLY_DATA | CO_FL_HANDSHAKE)) ==
+ CO_FL_EARLY_DATA) {
+ h2_wake_some_streams(h2c, 0, 0);
+ conn->flags &= ~CO_FL_EARLY_DATA;
+ }
if (conn->flags & CO_FL_ERROR || conn_xprt_read0_pending(conn) ||
h2c->st0 == H2_CS_ERROR2 || h2c->flags & H2_CF_GOAWAY_FAILED ||
(eb_is_empty(&h2c->streams_by_id) && h2c->last_sid >= 0 &&
ret = cs->data_cb->wake ? cs->data_cb->wake(cs) : 0;
+ /* If we had early data, and we're done with the handshake
+ * then whe know the data are safe, and we can remove the flag.
+ */
+ if ((conn->flags & (CO_FL_EARLY_DATA | CO_FL_EARLY_SSL_HS | CO_FL_HANDSHAKE)) ==
+ CO_FL_EARLY_DATA)
+ conn->flags &= ~CO_FL_EARLY_DATA;
if (ret >= 0)
cs_update_mux_polling(cs);
return ret;
* the handshake.
*/
if ((conn->flags & (CO_FL_EARLY_DATA | CO_FL_EARLY_SSL_HS)) == CO_FL_EARLY_DATA) {
- conn->flags &= ~CO_FL_EARLY_DATA;
task_wakeup(si_task(si), TASK_WOKEN_MSG);
}