[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 01/29: Refactoring: check whether memory block is resiza
From: |
gnunet |
Subject: |
[libmicrohttpd] 01/29: Refactoring: check whether memory block is resizable |
Date: |
Tue, 20 Jun 2023 22:24:14 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit eaa3be77c3aa003103a389e19debd672cd20fb4c
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Thu Nov 24 10:26:57 2022 +0300
Refactoring: check whether memory block is resizable
Instead of using some heuristics to determine which block is resizable,
use new special function to check
---
src/microhttpd/connection.c | 114 ++++++++++++++++++++++++++------------------
src/microhttpd/memorypool.c | 32 +++++++++++++
src/microhttpd/memorypool.h | 14 ++++++
3 files changed, 113 insertions(+), 47 deletions(-)
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 859ca820..f3e139a2 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -276,57 +276,59 @@ MHD_connection_alloc_memory_ (struct MHD_Connection
*connection,
{
struct MHD_Connection *const c = connection; /* a short alias */
struct MemoryPool *const pool = c->pool; /* a short alias */
- size_t need_to_free; /**< The required amount of free memory */
+ size_t need_to_be_freed; /**< The required amount of additional free memory
*/
void *res;
- res = MHD_pool_try_alloc (pool, size, &need_to_free);
- if (NULL == res)
+ res = MHD_pool_try_alloc (pool, size, &need_to_be_freed);
+ if (NULL != res)
+ return res;
+
+ if (MHD_pool_is_resizable_inplace (pool,
+ c->write_buffer,
+ c->write_buffer_size))
{
- if (NULL != c->write_buffer)
+ if (c->write_buffer_size - c->write_buffer_append_offset >=
+ need_to_be_freed)
{
- /* The connection is in the sending phase */
- mhd_assert (MHD_CONNECTION_START_REPLY <= c->state);
- if (c->write_buffer_size - c->write_buffer_append_offset >= need_to_free)
- {
- char *buf;
- const size_t new_buf_size = c->write_buffer_size - need_to_free;
- buf = MHD_pool_reallocate (pool,
- c->write_buffer,
- c->write_buffer_size,
- new_buf_size);
- mhd_assert (c->write_buffer == buf);
- mhd_assert (c->write_buffer_append_offset <= new_buf_size);
- mhd_assert (c->write_buffer_send_offset <= new_buf_size);
- c->write_buffer_size = new_buf_size;
- c->write_buffer = buf;
- }
- else
- return NULL;
+ char *buf;
+ const size_t new_buf_size = c->write_buffer_size - need_to_be_freed;
+ buf = MHD_pool_reallocate (pool,
+ c->write_buffer,
+ c->write_buffer_size,
+ new_buf_size);
+ mhd_assert (c->write_buffer == buf);
+ mhd_assert (c->write_buffer_append_offset <= new_buf_size);
+ mhd_assert (c->write_buffer_send_offset <= new_buf_size);
+ c->write_buffer_size = new_buf_size;
+ c->write_buffer = buf;
}
- else if (NULL != c->read_buffer)
+ else
+ return NULL;
+ }
+ else if (MHD_pool_is_resizable_inplace (pool,
+ c->read_buffer,
+ c->read_buffer_size))
+ {
+ if (c->read_buffer_size - c->read_buffer_offset >= need_to_be_freed)
{
- /* The connection is in the receiving phase */
- if (c->read_buffer_size - c->read_buffer_offset >= need_to_free)
- {
- char *buf;
- const size_t new_buf_size = c->read_buffer_size - need_to_free;
- buf = MHD_pool_reallocate (pool,
- c->read_buffer,
- c->read_buffer_size,
- new_buf_size);
- mhd_assert (c->read_buffer == buf);
- mhd_assert (c->read_buffer_offset <= new_buf_size);
- c->read_buffer_size = new_buf_size;
- c->read_buffer = buf;
- }
- else
- return NULL;
+ char *buf;
+ const size_t new_buf_size = c->read_buffer_size - need_to_be_freed;
+ buf = MHD_pool_reallocate (pool,
+ c->read_buffer,
+ c->read_buffer_size,
+ new_buf_size);
+ mhd_assert (c->read_buffer == buf);
+ mhd_assert (c->read_buffer_offset <= new_buf_size);
+ c->read_buffer_size = new_buf_size;
+ c->read_buffer = buf;
}
else
return NULL;
- res = MHD_pool_allocate (pool, size, true);
- mhd_assert (NULL != res); /* It has been checked that pool has enough
space */
}
+ else
+ return NULL;
+ res = MHD_pool_allocate (pool, size, true);
+ mhd_assert (NULL != res); /* It has been checked that pool has enough space
*/
return res;
}
@@ -1195,10 +1197,15 @@ try_ready_chunked_body (struct MHD_Connection
*connection,
/* Limit the buffer size to the largest usable size for chunks */
if ( (max_chunk + max_chunk_overhead) < size)
size = max_chunk + max_chunk_overhead;
- connection->write_buffer = MHD_pool_reallocate (connection->pool,
- connection->write_buffer,
- connection->
- write_buffer_size, size);
+ mhd_assert ((NULL == connection->write_buffer) || \
+ MHD_pool_is_resizable_inplace (connection->pool, \
+ connection->write_buffer, \
+ connection->write_buffer_size));
+ connection->write_buffer =
+ MHD_pool_reallocate (connection->pool,
+ connection->write_buffer,
+ connection->write_buffer_size,
+ size);
mhd_assert (NULL != connection->write_buffer);
connection->write_buffer_size = size;
}
@@ -1556,6 +1563,15 @@ try_grow_read_buffer (struct MHD_Connection *connection,
}
new_size = connection->read_buffer_size + grow_size;
}
+ /* Make sure that read buffer will not be moved */
+ if ((NULL != connection->read_buffer) &&
+ ! MHD_pool_is_resizable_inplace (connection->pool,
+ connection->read_buffer,
+ connection->read_buffer_size))
+ {
+ mhd_assert (0);
+ return false;
+ }
/* we can actually grow the buffer, do it! */
rb = MHD_pool_reallocate (connection->pool,
connection->read_buffer,
@@ -1605,6 +1621,8 @@ connection_shrink_read_buffer (struct MHD_Connection
*connection)
}
else
{
+ mhd_assert (MHD_pool_is_resizable_inplace (c->pool, c->read_buffer, \
+ c->read_buffer_size));
new_buf = MHD_pool_reallocate (c->pool, c->read_buffer,
c->read_buffer_size,
c->read_buffer_offset);
mhd_assert (c->read_buffer == new_buf);
@@ -1618,8 +1636,7 @@ connection_shrink_read_buffer (struct MHD_Connection
*connection)
* Allocate the maximum available amount of memory from MemoryPool
* for write buffer.
* @param connection the connection whose write buffer is being manipulated
- * @return the size of free space in write buffer, may be smaller
- * than requested size.
+ * @return the size of the free space in the write buffer
*/
static size_t
connection_maximize_write_buffer (struct MHD_Connection *connection)
@@ -1642,6 +1659,9 @@ connection_maximize_write_buffer (struct MHD_Connection
*connection)
* MHD_pool_reallocate () may return the new position only if buffer was
* allocated 'from_end' or is not the last allocation,
* which should not happen. */
+ mhd_assert ((NULL == c->write_buffer) || \
+ MHD_pool_is_resizable_inplace (pool, c->write_buffer, \
+ c->write_buffer_size));
new_buf = MHD_pool_reallocate (pool,
c->write_buffer,
c->write_buffer_size,
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index 8d80f888..fbc94659 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -426,6 +426,38 @@ MHD_pool_allocate (struct MemoryPool *pool,
}
+/**
+ * Checks whether allocated block is re-sizable in-place.
+ * If block is not re-sizable in-place, it still could be shrunk, but freed
+ * memory will not be re-used until reset of the pool.
+ * @param pool the memory pool to use
+ * @param block the pointer to the allocated block to check
+ * @param block_size the size of the allocated @a block
+ * @return true if block can be resized in-place in the optimal way,
+ * false otherwise
+ */
+bool
+MHD_pool_is_resizable_inplace (struct MemoryPool *pool,
+ void *block,
+ size_t block_size)
+{
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
+ mhd_assert (block != NULL || block_size == 0);
+ mhd_assert (pool->size >= block_size);
+ if (NULL != block)
+ {
+ const size_t block_offset = mp_ptr_diff_ (block, pool->memory);
+ mhd_assert (mp_ptr_le_ (pool->memory, block));
+ mhd_assert (pool->size >= block_offset);
+ mhd_assert (pool->size >= block_offset + block_size);
+ return (pool->pos ==
+ ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size));
+ }
+ return false; /* Unallocated blocks cannot be resized in-place */
+}
+
+
/**
* Try to allocate @a size bytes memory area from the @a pool.
*
diff --git a/src/microhttpd/memorypool.h b/src/microhttpd/memorypool.h
index 49bbcbe1..18c8e63c 100644
--- a/src/microhttpd/memorypool.h
+++ b/src/microhttpd/memorypool.h
@@ -87,6 +87,20 @@ MHD_pool_allocate (struct MemoryPool *pool,
size_t size,
bool from_end);
+/**
+ * Checks whether allocated block is re-sizable in-place.
+ * If block is not re-sizable in-place, it still could be shrunk, but freed
+ * memory will not be re-used until reset of the pool.
+ * @param pool the memory pool to use
+ * @param block the pointer to the allocated block to check
+ * @param block_size the size of the allocated @a block
+ * @return true if block can be resized in-place in the optimal way,
+ * false otherwise
+ */
+bool
+MHD_pool_is_resizable_inplace (struct MemoryPool *pool,
+ void *block,
+ size_t block_size);
/**
* Try to allocate @a size bytes memory area from the @a pool.
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [libmicrohttpd] branch master updated (8dc93b08 -> f02888d4), gnunet, 2023/06/20
- [libmicrohttpd] 03/29: microhttpd.h: fixed typos in comments, gnunet, 2023/06/20
- [libmicrohttpd] 04/29: Renamed connection state for clarity, gnunet, 2023/06/20
- [libmicrohttpd] 02/29: Re-implemented parsing of the request line from scratch., gnunet, 2023/06/20
- [libmicrohttpd] 08/29: tests: minor improvemnts, gnunet, 2023/06/20
- [libmicrohttpd] 07/29: Removed request line and headers processing old functions and variables, gnunet, 2023/06/20
- [libmicrohttpd] 09/29: daemon: added debug member to avoid accept4() usage, gnunet, 2023/06/20
- [libmicrohttpd] 01/29: Refactoring: check whether memory block is resizable,
gnunet <=
- [libmicrohttpd] 06/29: Re-implemented parsing of the request headers and footers from scratch., gnunet, 2023/06/20
- [libmicrohttpd] 12/29: Added back testing with socat as a fallback option, gnunet, 2023/06/20
- [libmicrohttpd] 05/29: Request body processing: removed impossible code paths, gnunet, 2023/06/20
- [libmicrohttpd] 16/29: Added tests with single and double folded header, gnunet, 2023/06/20
- [libmicrohttpd] 21/29: process_request_body(): minor readability improvementы, gnunet, 2023/06/20
- [libmicrohttpd] 11/29: testzzuf: re-worked zzuf testing, gnunet, 2023/06/20
- [libmicrohttpd] 10/29: testzzuf: added special debug functions, gnunet, 2023/06/20
- [libmicrohttpd] 22/29: Minor refactoring for partially processed request body, gnunet, 2023/06/20
- [libmicrohttpd] 14/29: Added test with folded header placed last, gnunet, 2023/06/20
- [libmicrohttpd] 15/29: Added test with large folded header, gnunet, 2023/06/20