|
|
@@ -238,12 +238,18 @@ sendfile_adapter (struct MHD_Connection *connection)
|
|
|
#else /* HAVE_SENDFILE64 */
|
|
|
off64_t offset;
|
|
|
#endif /* HAVE_SENDFILE64 */
|
|
|
+ const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
|
|
|
+ size_t send_size;
|
|
|
mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
|
|
|
|
|
|
offsetu64 = connection->response_write_position + connection->response->fd_off;
|
|
|
left = connection->response->total_size - connection->response_write_position;
|
|
|
- if (left > SSIZE_MAX)
|
|
|
- left = SSIZE_MAX;
|
|
|
+ /* Do not allow system to stick sending on single fast connection:
|
|
|
+ * use 128KiB chunks (2MiB for thread-per-connection). */
|
|
|
+ if (!used_thr_p_c)
|
|
|
+ send_size = (left > 0x20000) ? 0x20000 : (size_t) left;
|
|
|
+ else
|
|
|
+ send_size = (left > 0x200000) ? 0x200000 : (size_t) left;
|
|
|
#ifndef HAVE_SENDFILE64
|
|
|
if ((uint64_t)OFF_T_MAX < offsetu64)
|
|
|
{ /* Retry to send with standard 'send()'. */
|
|
|
@@ -254,7 +260,7 @@ sendfile_adapter (struct MHD_Connection *connection)
|
|
|
ret = sendfile (connection->socket_fd,
|
|
|
file_fd,
|
|
|
&offset,
|
|
|
- left);
|
|
|
+ send_size);
|
|
|
#else /* HAVE_SENDFILE64 */
|
|
|
if ((uint64_t)OFF64_T_MAX < offsetu64)
|
|
|
{ /* Retry to send with standard 'send()'. */
|
|
|
@@ -265,7 +271,7 @@ sendfile_adapter (struct MHD_Connection *connection)
|
|
|
ret = sendfile64 (connection->socket_fd,
|
|
|
file_fd,
|
|
|
&offset,
|
|
|
- left);
|
|
|
+ send_size);
|
|
|
#endif /* HAVE_SENDFILE64 */
|
|
|
if (0 > ret)
|
|
|
{
|
|
|
@@ -292,7 +298,7 @@ sendfile_adapter (struct MHD_Connection *connection)
|
|
|
return MHD_ERR_AGAIN_;
|
|
|
}
|
|
|
#ifdef EPOLL_SUPPORT
|
|
|
- else if (left > (uint64_t)ret)
|
|
|
+ else if (send_size > (size_t)ret)
|
|
|
connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
|
|
|
#endif /* EPOLL_SUPPORT */
|
|
|
return ret;
|