CO_SRC_BIND = 0x0008, /* bind to a specific source address when connecting */
};
-/* flags that can be passed to xprt->snd_buf() */
+/* flags that can be passed to xprt->rcv_buf() and mux->rcv_buf() */
+enum {
+ CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */
+};
+
+/* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */
enum {
CO_SFL_MSG_MORE = 0x0001, /* More data to come afterwards */
CO_SFL_STREAMER = 0x0002, /* Producer is continuously streaming data */
* proceed. Stream errors are reported in h2s->errcode and connection errors
* in h2c->errcode.
*/
-static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count)
+static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count, int flags)
{
struct h2c *h2c = h2s->h2c;
const uint8_t *hdrs = (uint8_t *)h2c->dbuf->p;
* always empty except maybe for trailers, so these operations almost
* never happen.
*/
- if (unlikely(buf->o)) {
+ if (flags & CO_RFL_BUF_WET) {
/* need to let the output buffer flush and
* mark the buffer for later wake up.
*/
* frame header and ensured that the frame was complete or the buffer full. It
* changes the frame state to FRAME_A once done.
*/
-static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count)
+static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count, int flags)
{
struct h2c *h2c = h2s->h2c;
int block1, block2;
switch (h2c->dft) {
case H2_FT_HEADERS:
- ret = h2_frt_decode_headers(h2s, buf, count);
+ ret = h2_frt_decode_headers(h2s, buf, count, flags);
break;
case H2_FT_DATA:
- ret = h2_frt_transfer_data(h2s, buf, count);
+ ret = h2_frt_transfer_data(h2s, buf, count, flags);
break;
default:
break;
}
- ret = conn->mux->rcv_buf(cs, ic->buf, max, 0);
+ ret = conn->mux->rcv_buf(cs, ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
if (cs->flags & CS_FL_RCV_MORE)
si->flags |= SI_FL_WAIT_ROOM;