summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2022-04-21 10:02:29 +0000
committerYann Ylavic <ylavic@apache.org>2022-04-21 10:02:29 +0000
commit567a50205fc4556bd5f79eb9f087249b9e3ee221 (patch)
tree6d41f5a211868d67f97767a7737434b5a21bc080 /server
parent4d1ca7bd74ba5c25666245b93c932a2b34aafc73 (diff)
downloadhttpd-567a50205fc4556bd5f79eb9f087249b9e3ee221.tar.gz
core: Disable TCP_NOPUSH optimization on OSX. BZ 66019.
OSX supports TCP_NOPUSH but does not release the data retained (in TCP stack) when the option is unset. It seems that unsetting it before the last write does not help either so just disable the optimization for OSX in the core output filter to avoid uncontrollable transmission delays. * server/core_filters.c(): Add the sock_nopush() helper that does nothing on OSX and platforms not supporting TCP_NOPUSH or TCP_CORK. * server/core_filters.c(send_brigade_nonblocking): Use sock_nopush() instead of apr_socket_opt_set() for APR_TCP_NOPUSH option. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1900100 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r--server/core_filters.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/server/core_filters.c b/server/core_filters.c
index c0275dc0de..0f7a093a3a 100644
--- a/server/core_filters.c
+++ b/server/core_filters.c
@@ -493,6 +493,18 @@ static void delete_meta_bucket(apr_bucket *bucket)
apr_bucket_delete(bucket);
}
+static APR_INLINE void sock_nopush(apr_socket_t *s, int to)
+{
+ /* Disable TCP_NOPUSH handling on OSX since unsetting it won't push
+ * retained data, which might introduce delays if further data don't
+ * come soon enough or cause the last chunk to be sent only when the
+ * connection is shutdown (e.g. after KeepAliveTimeout).
+ */
+#if APR_TCP_NOPUSH_FLAG && !defined(__APPLE__)
+ (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, to);
+#endif
+}
+
static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
apr_bucket_brigade *bb,
core_output_ctx_t *ctx,
@@ -514,7 +526,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
#if APR_HAS_SENDFILE
if (can_sendfile_bucket(bucket)) {
if (nvec > 0) {
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1);
+ sock_nopush(s, 1);
rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
if (rv != APR_SUCCESS) {
goto cleanup;
@@ -544,7 +556,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
nbytes = 0;
nvec = 0;
}
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
+ sock_nopush(s, 0);
rv = apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
}
@@ -572,7 +584,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
/* Make sure that these new data fit in our iovec. */
if (nvec == ctx->nvec) {
if (nvec == NVEC_MAX) {
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1);
+ sock_nopush(s, 1);
rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
if (rv != APR_SUCCESS) {
goto cleanup;
@@ -610,7 +622,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
if (nbytes > sconf->flush_max_threshold
&& next != APR_BRIGADE_SENTINEL(bb)
&& next->length && !is_in_memory_bucket(next)) {
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1);
+ sock_nopush(s, 1);
rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
if (rv != APR_SUCCESS) {
goto cleanup;
@@ -624,7 +636,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
}
cleanup:
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
+ sock_nopush(s, 0);
return rv;
}