diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-06-16 23:15:13 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-06-17 21:27:18 +0300 |
commit | 55dc42e6045022da41c538d226874dbf563a85ed (patch) | |
tree | 708b26976b0111123dd61f7dd5142a27a43c3dd9 | |
parent | a275ae63537380c41cfe145ec4e00dd796e0992c (diff) | |
download | libmicrohttpd-55dc42e6045022da41c538d226874dbf563a85ed.tar.gz libmicrohttpd-55dc42e6045022da41c538d226874dbf563a85ed.zip |
Optimised read buffer allocation
-rw-r--r-- | src/microhttpd/connection.c | 66 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 2 |
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 | */ |
1580 | static int | 1582 | static bool |
1581 | try_grow_read_buffer (struct MHD_Connection *connection) | 1583 | try_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 |