Hi,
Some years ago reyk@ mentioned that the current socket splicing
semantics is suboptimal. When used with persistent http connections,
the kernel does not inform user land when the maximum splicing
lenght has been reached. The file descriptor does not get active
when the last byte within the limit has been spliced, but only after
additional data has arrived.
When mikeb@ implemented idle timeouts, he had the idea to pass an
ETIMEDOUT error to user land. This creates an event on the socket
that can be checked with select(2). Similary this diff passes an
EFBIG error when the maximum splicing length is reached. So the
kernel passes control to user land immediately. This can be used
to log the end of an http request.
reyk@, mikeb@: What do you think about this idea?
bluhm
diff --git a/kern/uipc_socket.c b/kern/uipc_socket.c
index bc4f3d1..20f79f2 100644
--- a/kern/uipc_socket.c
+++ b/kern/uipc_socket.c
@@ -1173,7 +1173,8 @@ somove(struct socket *so, int wait)
error = EPIPE;
goto release;
}
- if (sosp->so_error && sosp->so_error != ETIMEDOUT) {
+ if (sosp->so_error && sosp->so_error != ETIMEDOUT &&
+ sosp->so_error != EFBIG) {
error = sosp->so_error;
goto release;
}
@@ -1388,6 +1389,8 @@ somove(struct socket *so, int wait)
release:
sosp->so_state &= ~SS_ISSENDING;
+ if (!error && maxreached && so->so_splicemax == so->so_splicelen)
+ error = EFBIG;
if (error)
so->so_error = error;
if (((so->so_state & SS_CANTRCVMORE) && so->so_rcv.sb_cc == 0) ||