CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */
CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */
CO_RFL_BUF_NOT_STUCK = 0x0010, /* Buffer is not stuck. Optims are possible during data copy */
+ CO_RFL_MAY_SPLICE = 0x0020, /* The producer can use the kernel splicing */
};
/* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */
int (*wake)(struct connection *conn); /* mux-layer callback to report activity, mandatory */
size_t (*rcv_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); /* Called from the upper layer to get data */
size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); /* Called from the upper layer to send data */
+ size_t (*init_fastfwd)(struct stconn *sc, struct buffer *input, size_t count, unsigned int may_splice); /* Callback to fill the SD iobuf */
+ void (*done_fastfwd)(struct stconn *sc); /* Callback to terminate fast data forwarding */
+ int (*fastfwd)(struct stconn *sc, unsigned int count, unsigned int flags); /* Callback to init fast data forwarding */
+ int (*resume_fastfwd)(struct stconn *sc, unsigned int flags); /* Callback to resume fast data forwarding */
int (*rcv_pipe)(struct stconn *sc, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */
int (*snd_pipe)(struct stconn *sc, struct pipe *pipe); /* send-to-pipe callback */
void (*shutr)(struct stconn *sc, enum co_shr_mode); /* shutr function */
return (se->iobuf.data + (se->iobuf.pipe ? se->iobuf.pipe->data : 0));
}
+static inline size_t se_init_ff(struct sedesc *se, struct buffer *input, size_t count, unsigned int may_splice)
+{
+ size_t ret = 0;
+
+ if (se_fl_test(se, SE_FL_T_MUX)) {
+ const struct mux_ops *mux = se->conn->mux;
+
+ se->iobuf.flags &= ~IOBUF_FL_FF_BLOCKED;
+ if (mux->init_fastfwd && mux->done_fastfwd) {
+ ret = mux->init_fastfwd(se->sc, input, count, may_splice);
+ if ((se->iobuf.flags & IOBUF_FL_FF_BLOCKED) && !(se->sc->wait_event.events & SUB_RETRY_SEND)) {
+ /* The SC must be subs for send to be notify when some
+ * space is made
+ */
+ mux->subscribe(se->sc, SUB_RETRY_SEND, &se->sc->wait_event);
+ }
+ goto end;
+ }
+ }
+ se->iobuf.flags |= IOBUF_FL_NO_FF;
+
+ end:
+ return ret;
+}
+
+static inline void se_done_ff(struct sedesc *se)
+{
+ if (se_fl_test(se, SE_FL_T_MUX)) {
+ const struct mux_ops *mux = se->conn->mux;
+
+ BUG_ON(!mux->done_fastfwd);
+ mux->done_fastfwd(se->sc);
+ }
+}
/* stream connector version */
static forceinline void sc_ep_zero(struct stconn *sc)