gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]