aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--tcp_splice.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/tcp_splice.c b/tcp_splice.c
index 565596d..3fd33a1 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -497,9 +497,17 @@ static int tcp_splice_forward(struct ctx *c,
flow_trace(conn, "%zi from read-side call", readlen);
- if (!readlen) {
- conn_event(conn, FIN_RCVD(fromsidei));
- } else if (readlen > 0) {
+ if (readlen <= 0) {
+ if (!readlen) /* EOF */
+ conn_event(conn, FIN_RCVD(fromsidei));
+
+ /* We're either blocked or at EOF on the read side, and
+ * there's nothing in the pipe so there's nothing to do
+ * write side either.
+ */
+ if (!conn->pending[fromsidei])
+ break;
+ } else {
conn->pending[fromsidei] += readlen;
if (readlen >= (long)c->tcp.pipe_size * 90 / 100)
@@ -531,9 +539,12 @@ static int tcp_splice_forward(struct ctx *c,
conn->pending[fromsidei] -= written;
- if (conn->events & FIN_RCVD(fromsidei) &&
- !conn->pending[fromsidei])
+ if (!conn->pending[fromsidei] && readlen <= 0) {
+ /* Read side is EOF or EAGAIN, and we emptied the pipe.
+ * No more we can do for now.
+ */
break;
+ }
}
/* We need write-side wakeups if and only if we have data in the pipe to