}
#endif
+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_filter_ctx_t *ctx,
#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;
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);
}
/* 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;
if (nbytes > conf->flush_max_threshold
&& next != APR_BRIGADE_SENTINEL(bb)
&& !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;
}
cleanup:
- (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
+ sock_nopush(s, 0);
return rv;
}