libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 41eb046c9c1ebb6fdcad0417eccc998d9939eceb
parent 6f646947421e41312def7555408184cd7dec0a3c
Author: Evgeny Grin <k2k@narod.ru>
Date:   Mon,  2 Oct 2017 00:44:30 +0300

Implemented usage of readahead buffer for sendfile() on FreeBSD 11 and later

Diffstat:
Msrc/microhttpd/connection.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/microhttpd/connection.h | 9+++++++++
Msrc/microhttpd/daemon.c | 3+++
3 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -118,6 +118,54 @@ /** + * sendfile() chuck size + */ +#define MHD_SENFILE_CHUNK_ (0x20000) + +/** + * sendfile() chuck size for thread-per-connection + */ +#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000) + +#ifdef HAVE_FREEBSD_SENDFILE +#ifdef SF_FLAGS +/** + * FreeBSD sendfile() flags + */ +static int freebsd_sendfile_flags_; + +/** + * FreeBSD sendfile() flags for thread-per-connection + */ +static int freebsd_sendfile_flags_thd_p_c_; +#endif /* SF_FLAGS */ +/** + * Initialises static variables + */ +void +MHD_conn_init_static_ (void) +{ +/* FreeBSD 11 and later allow to specify read-ahead size + * and handles SF_NODISKIO differently. + * SF_FLAGS defined only on FreeBSD 11 and later. */ +#ifdef SF_FLAGS + long sys_page_size = sysconf (_SC_PAGESIZE); + if (0 > sys_page_size) + { /* Failed to get page size. */ + freebsd_sendfile_flags_ = SF_NODISKIO; + freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO; + } + else + { + freebsd_sendfile_flags_ = + SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO); + freebsd_sendfile_flags_thd_p_c_ = + SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size), SF_NODISKIO); + } +#endif /* SF_FLAGS */ +} +#endif /* HAVE_FREEBSD_SENDFILE */ +/** * Callback for receiving data from the socket. * * @param connection the MHD connection structure @@ -252,9 +300,10 @@ sendfile_adapter (struct MHD_Connection *connection) #endif /* HAVE_LINUX_SENDFILE */ #ifdef HAVE_FREEBSD_SENDFILE off_t sent_bytes; + int flags = 0; #endif const bool used_thr_p_c = (0 != (connection->daemon->options & MHD_USE_THREAD_PER_CONNECTION)); - const size_t chunk_size = used_thr_p_c ? 0x200000 : 0x20000; + const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_; size_t send_size = 0; mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender); @@ -311,13 +360,17 @@ sendfile_adapter (struct MHD_Connection *connection) connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; #endif /* EPOLL_SUPPORT */ #elif defined(HAVE_FREEBSD_SENDFILE) +#ifdef SF_FLAGS + flags = used_thr_p_c ? + freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_; +#endif /* SF_FLAGS */ if (0 != sendfile (file_fd, connection->socket_fd, (off_t) offsetu64, send_size, NULL, &sent_bytes, - 0)) + flags)) { const int err = MHD_socket_get_error_(); if (MHD_SCKT_ERR_IS_EAGAIN_(err) || @@ -336,6 +389,7 @@ sendfile_adapter (struct MHD_Connection *connection) return MHD_ERR_AGAIN_; } mhd_assert (0 < sent_bytes); + mhd_assert (SSIZE_MAX >= sent_bytes); ret = (ssize_t)sent_bytes; #endif /* HAVE_FREEBSD_SENDFILE */ return ret; diff --git a/src/microhttpd/connection.h b/src/microhttpd/connection.h @@ -62,6 +62,15 @@ #define MHD_ERR_INVAL_ (-3078) +#ifdef HAVE_FREEBSD_SENDFILE +/** + * Initialises static variables + */ +void +MHD_conn_init_static_ (void); +#endif /* HAVE_FREEBSD_SENDFILE */ + + /** * Set callbacks for this connection to those for HTTP. * diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -6702,6 +6702,9 @@ MHD_init(void) gnutls_global_init (); #endif /* HTTPS_SUPPORT */ MHD_monotonic_sec_counter_init(); +#ifdef HAVE_FREEBSD_SENDFILE + MHD_conn_init_static_ (); +#endif /* HAVE_FREEBSD_SENDFILE */ }