aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-08-23 22:20:50 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-08-23 22:20:50 +0300
commit95d1725ce3f2deafa33f697f5cb54ab6c557d415 (patch)
tree3f092a454dcced364d42abe82ae6d6b35d056695
parent5c8b5aefd0c3859fb830a64512f318bac4c745b5 (diff)
downloadlibmicrohttpd-95d1725ce3f2deafa33f697f5cb54ab6c557d415.tar.gz
libmicrohttpd-95d1725ce3f2deafa33f697f5cb54ab6c557d415.zip
Connection: allocate persistent connection memory with helper
The new helper function may reduce read or write buffer to make available the required amount of memory. This allow to use entire pool for read or write buffer.
-rw-r--r--src/microhttpd/connection.c86
1 files changed, 77 insertions, 9 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 5cbb30ed..89528031 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -186,6 +186,77 @@ str_conn_error_ (ssize_t mhd_err_code)
186} 186}
187 187
188 188
189/**
190 * Allocate memory from connection's memory pool.
191 * If memory pool doesn't have enough free memory but read of write buffer
192 * have some unused memory, the size of the buffer will be reduced as needed.
193 * @param connection the connection to use
194 * @param size the size of allocated memory area
195 * @return pointer to allocated memory region in the pool or
196 * NULL if no memory is available
197 */
198static void*
199connection_alloc_memory (struct MHD_Connection *connection,
200 size_t size)
201{
202 struct MHD_Connection *const c = connection; /* a short alias */
203 struct MemoryPool *const pool = c->pool; /* a short alias */
204 size_t required_free_size; /**< The required amount of free memory */
205 size_t pool_free; /**< The amount of free memory in the pool */
206 void *res;
207
208 required_free_size = MHD_pool_alloc_size (size);
209 pool_free = MHD_pool_get_free (pool);
210 if (pool_free < required_free_size)
211 {
212 size_t need_to_free = required_free_size - pool_free;
213 mhd_assert (MHD_pool_alloc_size (need_to_free) == need_to_free);
214 if (NULL != c->write_buffer)
215 {
216 /* The connection is in the sending phase */
217 mhd_assert (MHD_CONNECTION_START_REPLY <= c->state);
218 if (c->write_buffer_size - c->write_buffer_append_offset >= need_to_free)
219 {
220 char *buf;
221 buf = MHD_pool_reallocate (pool,
222 c->write_buffer,
223 c->write_buffer_size,
224 c->write_buffer_size - need_to_free);
225 mhd_assert (c->write_buffer == buf);
226#ifdef NDEBUG
227 (void) buf; /* mute compiler warning */
228#endif
229 }
230 else
231 return NULL;
232 }
233 else if (NULL != c->read_buffer)
234 {
235 /* The connection is in the receiving phase */
236 if (c->read_buffer_size - c->read_buffer_offset >= need_to_free)
237 {
238 char *buf;
239 buf = MHD_pool_reallocate (pool,
240 c->read_buffer,
241 c->read_buffer_size,
242 c->read_buffer_size - need_to_free);
243 mhd_assert (c->read_buffer == buf);
244#ifdef NDEBUG
245 (void) buf; /* mute compiler warning */
246#endif
247 }
248 else
249 return NULL;
250 }
251 else
252 return NULL;
253 }
254 res = MHD_pool_allocate (pool, size, true);
255 mhd_assert (NULL != res); /* It has been checked that pool has enough space */
256 return res;
257}
258
259
189#endif /* HAVE_MESSAGES */ 260#endif /* HAVE_MESSAGES */
190 261
191/** 262/**
@@ -365,9 +436,8 @@ MHD_set_connection_value_n_nocheck_ (struct MHD_Connection *connection,
365{ 436{
366 struct MHD_HTTP_Header *pos; 437 struct MHD_HTTP_Header *pos;
367 438
368 pos = MHD_pool_allocate (connection->pool, 439 pos = connection_alloc_memory (connection,
369 sizeof (struct MHD_HTTP_Header), 440 sizeof (struct MHD_HTTP_Header));
370 true);
371 if (NULL == pos) 441 if (NULL == pos)
372 return MHD_NO; 442 return MHD_NO;
373 pos->header = (char *) key; 443 pos->header = (char *) key;
@@ -920,9 +990,8 @@ try_ready_normal_body (struct MHD_Connection *connection)
920 if (NULL != connection->resp_iov.iov) 990 if (NULL != connection->resp_iov.iov)
921 return MHD_YES; 991 return MHD_YES;
922 copy_size = response->data_iovcnt * sizeof(MHD_iovec_); 992 copy_size = response->data_iovcnt * sizeof(MHD_iovec_);
923 connection->resp_iov.iov = MHD_pool_allocate (connection->pool, 993 connection->resp_iov.iov = connection_alloc_memory (connection,
924 copy_size, 994 copy_size);
925 true);
926 if (NULL == connection->resp_iov.iov) 995 if (NULL == connection->resp_iov.iov)
927 { 996 {
928 MHD_mutex_unlock_chk_ (&response->mutex); 997 MHD_mutex_unlock_chk_ (&response->mutex);
@@ -2503,9 +2572,8 @@ parse_cookie_header (struct MHD_Connection *connection)
2503 &hdr, 2572 &hdr,
2504 &hdr_len)) 2573 &hdr_len))
2505 return MHD_YES; 2574 return MHD_YES;
2506 cpy = MHD_pool_allocate (connection->pool, 2575 cpy = connection_alloc_memory (connection,
2507 hdr_len + 1, 2576 hdr_len + 1);
2508 true);
2509 if (NULL == cpy) 2577 if (NULL == cpy)
2510 { 2578 {
2511#ifdef HAVE_MESSAGES 2579#ifdef HAVE_MESSAGES