#define QC_CF_CC_EMIT 0x00000001 /* A CONNECTION_CLOSE is set by the MUX */
#define QC_CF_BLK_MFCTL 0x00000002 /* sending blocked due to connection flow-control */
#define QC_CF_CONN_FULL 0x00000004 /* no stream buffers available on connection */
+#define QC_CF_APP_FINAL 0x00000008 /* The application layer was finalized */
struct qcc {
struct connection *conn;
}
ret = b_force_xfer(res, &pos, b_data(&pos));
- if (ret > 0) {
+ if (ret > 0)
h3c->flags |= H3_CF_SETTINGS_SENT;
- if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
- tasklet_wakeup(qcs->qcc->wait_event.tasklet);
- }
TRACE_LEAVE(H3_EV_TX_SETTINGS, qcs->qcc->conn, qcs);
return ret;
TRACE_PROTO("application layer initialized", QMUX_EV_QCC_NEW, qcc->conn);
- if (qcc->app_ops->finalize)
- qcc->app_ops->finalize(qcc->ctx);
-
TRACE_LEAVE(QMUX_EV_QCC_NEW, qcc->conn);
return 0;
if (qcc->flags & QC_CF_BLK_MFCTL)
return 0;
+ if (!(qcc->flags & QC_CF_APP_FINAL) && !eb_is_empty(&qcc->streams_by_id) &&
+ qcc->app_ops->finalize) {
+ /* Finalize the application layer before sending any stream.
+ * For h3 this consists in preparing the control stream data (SETTINGS h3).
+ */
+ qcc->app_ops->finalize(qcc->ctx);
+ qcc->flags |= QC_CF_APP_FINAL;
+ }
+
/* loop through all streams, construct STREAM frames if data available.
* TODO optimize the loop to favor streams which are not too heavy.
*/