aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-16 23:15:13 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-17 21:27:18 +0300
commit55dc42e6045022da41c538d226874dbf563a85ed (patch)
tree708b26976b0111123dd61f7dd5142a27a43c3dd9
parenta275ae63537380c41cfe145ec4e00dd796e0992c (diff)
downloadlibmicrohttpd-55dc42e6045022da41c538d226874dbf563a85ed.tar.gz
libmicrohttpd-55dc42e6045022da41c538d226874dbf563a85ed.zip
Optimised read buffer allocation
-rw-r--r--src/microhttpd/connection.c66
-rw-r--r--src/microhttpd/internal.h2
2 files changed, 46 insertions, 22 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index a97844c2..877f514b 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1575,28 +1575,51 @@ get_date_string (char *date,
1575 * minimum necessary at that point. 1575 * minimum necessary at that point.
1576 * 1576 *
1577 * @param connection the connection 1577 * @param connection the connection
1578 * @return #MHD_YES on success, #MHD_NO on failure 1578 * @param required set to 'true' if grow is required, i.e. connection
1579 * will fail if no additional space is granted
1580 * @return 'true' on success, 'false' on failure
1579 */ 1581 */
1580static int 1582static bool
1581try_grow_read_buffer (struct MHD_Connection *connection) 1583try_grow_read_buffer (struct MHD_Connection *connection,
1584 bool required)
1582{ 1585{
1583 void *buf;
1584 size_t new_size; 1586 size_t new_size;
1587 size_t avail_size;
1585 1588
1589 avail_size = MHD_pool_get_free (connection->pool);
1590 if (0 == avail_size)
1591 return false; /* No more space available */
1586 if (0 == connection->read_buffer_size) 1592 if (0 == connection->read_buffer_size)
1587 new_size = connection->daemon->pool_size / 2; 1593 new_size = avail_size / 2; /* Use half of available buffer for reading */
1588 else 1594 else
1589 new_size = connection->read_buffer_size + MHD_BUF_INC_SIZE; 1595 {
1590 buf = MHD_pool_reallocate (connection->pool, 1596 size_t grow_size;
1591 connection->read_buffer, 1597
1592 connection->read_buffer_size, 1598 grow_size = avail_size / 8;
1593 new_size); 1599 if (MHD_BUF_INC_SIZE > grow_size)
1594 if (NULL == buf) 1600 { /* Shortage of space */
1595 return MHD_NO; 1601 if (!required)
1602 return false; /* Grow is not mandatory, leave some space in pool */
1603 else
1604 {
1605 /* Shortage of space, but grow is mandatory */
1606 static const size_t small_inc = MHD_BUF_INC_SIZE / 8;
1607 if (small_inc < avail_size)
1608 grow_size = small_inc;
1609 else
1610 grow_size = avail_size;
1611 }
1612 }
1613 new_size = connection->read_buffer_size + grow_size;
1614 }
1596 /* we can actually grow the buffer, do it! */ 1615 /* we can actually grow the buffer, do it! */
1597 connection->read_buffer = buf; 1616 connection->read_buffer = MHD_pool_reallocate (connection->pool,
1617 connection->read_buffer,
1618 connection->read_buffer_size,
1619 new_size);
1620 mhd_assert (NULL != connection->read_buffer);
1598 connection->read_buffer_size = new_size; 1621 connection->read_buffer_size = new_size;
1599 return MHD_YES; 1622 return true;
1600} 1623}
1601 1624
1602 1625
@@ -2097,7 +2120,7 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
2097 /* while reading headers, we always grow the 2120 /* while reading headers, we always grow the
2098 read buffer if needed, no size-check required */ 2121 read buffer if needed, no size-check required */
2099 if ( (connection->read_buffer_offset == connection->read_buffer_size) && 2122 if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
2100 (MHD_NO == try_grow_read_buffer (connection)) ) 2123 (!try_grow_read_buffer (connection, true)) )
2101 { 2124 {
2102 transmit_error_response (connection, 2125 transmit_error_response (connection,
2103 (connection->url != NULL) 2126 (connection->url != NULL)
@@ -2123,9 +2146,10 @@ MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
2123 case MHD_CONNECTION_CONTINUE_SENT: 2146 case MHD_CONNECTION_CONTINUE_SENT:
2124 if (connection->read_buffer_offset == connection->read_buffer_size) 2147 if (connection->read_buffer_offset == connection->read_buffer_size)
2125 { 2148 {
2126 if ((MHD_YES != try_grow_read_buffer (connection)) && 2149 const bool internal_poll = (0 != (connection->daemon->options &
2127 (0 != (connection->daemon->options & 2150 MHD_USE_INTERNAL_POLLING_THREAD));
2128 MHD_USE_INTERNAL_POLLING_THREAD))) 2151 if ( (!try_grow_read_buffer (connection, true)) &&
2152 internal_poll)
2129 { 2153 {
2130 /* failed to grow the read buffer, and the 2154 /* failed to grow the read buffer, and the
2131 client which is supposed to handle the 2155 client which is supposed to handle the
@@ -2244,8 +2268,7 @@ get_next_header_line (struct MHD_Connection *connection,
2244 { 2268 {
2245 /* not found, consider growing... */ 2269 /* not found, consider growing... */
2246 if ( (connection->read_buffer_offset == connection->read_buffer_size) && 2270 if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
2247 (MHD_NO == 2271 (!try_grow_read_buffer (connection, true)) )
2248 try_grow_read_buffer (connection)) )
2249 { 2272 {
2250 transmit_error_response (connection, 2273 transmit_error_response (connection,
2251 (NULL != connection->url) 2274 (NULL != connection->url)
@@ -3157,7 +3180,8 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
3157 in buffer to use per system call (if possible) */ 3180 in buffer to use per system call (if possible) */
3158 if (connection->read_buffer_offset + connection->daemon->pool_increment > 3181 if (connection->read_buffer_offset + connection->daemon->pool_increment >
3159 connection->read_buffer_size) 3182 connection->read_buffer_size)
3160 try_grow_read_buffer (connection); 3183 try_grow_read_buffer (connection,
3184 (connection->read_buffer_size == connection->read_buffer_offset));
3161 3185
3162 if (connection->read_buffer_size == connection->read_buffer_offset) 3186 if (connection->read_buffer_size == connection->read_buffer_offset)
3163 return; /* No space for receiving data. */ 3187 return; /* No space for receiving data. */
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 97ac050f..8dc813a2 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -93,7 +93,7 @@
93 93
94 94
95/** 95/**
96 * Minimum size by which MHD tries to increment read/write buffers. 96 * Minimum reasonable size by which MHD tries to increment read/write buffers.
97 * We usually begin with half the available pool space for the 97 * We usually begin with half the available pool space for the
98 * IO-buffer, but if absolutely needed we additively grow by the 98 * IO-buffer, but if absolutely needed we additively grow by the
99 * number of bytes given here (up to -- theoretically -- the full pool 99 * number of bytes given here (up to -- theoretically -- the full pool