Enabled body buffer shared memory segmentation.
Changeset #699 fixes shared memory allocation: continous buffer with requested size should be allocated or function failed. For body longer than 10 Mb, this allocation will definitely fails. For body buffer it is not required to send it in a single continous buffer, so, need to request minimum reasonable amount of shared memory and try to extend it, if possible or allocate next buffer.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <nxt_router.h>
|
||||
#include <nxt_http.h>
|
||||
#include <nxt_application.h>
|
||||
#include <nxt_port_memory_int.h>
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
@@ -500,15 +501,6 @@ nxt_app_msg_write_get_buf(nxt_task_t *task, nxt_app_wmsg_t *msg, size_t size)
|
||||
}
|
||||
|
||||
*msg->buf = b;
|
||||
|
||||
free_size = nxt_buf_mem_free_size(&b->mem);
|
||||
|
||||
if (nxt_slow_path(free_size < size)) {
|
||||
nxt_log(task, NXT_LOG_WARN, "requested buffer too big "
|
||||
"(%z < %z)", free_size, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free_size = nxt_buf_mem_free_size(&b->mem);
|
||||
@@ -824,8 +816,8 @@ nxt_int_t
|
||||
nxt_app_msg_write_raw(nxt_task_t *task, nxt_app_wmsg_t *msg, const u_char *c,
|
||||
size_t size)
|
||||
{
|
||||
size_t free_size, copy_size;
|
||||
nxt_buf_t *b;
|
||||
size_t free_size, copy_size;
|
||||
nxt_buf_t *b;
|
||||
|
||||
nxt_debug(task, "nxt_app_msg_write_raw: %uz", size);
|
||||
|
||||
@@ -833,30 +825,37 @@ nxt_app_msg_write_raw(nxt_task_t *task, nxt_app_wmsg_t *msg, const u_char *c,
|
||||
b = *msg->buf;
|
||||
|
||||
if (b == NULL) {
|
||||
b = nxt_port_mmap_get_buf(task, msg->port, size);
|
||||
free_size = nxt_min(size, PORT_MMAP_DATA_SIZE);
|
||||
|
||||
b = nxt_port_mmap_get_buf(task, msg->port, free_size);
|
||||
if (nxt_slow_path(b == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
*msg->buf = b;
|
||||
}
|
||||
|
||||
do {
|
||||
} else {
|
||||
free_size = nxt_buf_mem_free_size(&b->mem);
|
||||
|
||||
if (free_size > 0) {
|
||||
copy_size = nxt_min(free_size, size);
|
||||
|
||||
b->mem.free = nxt_cpymem(b->mem.free, c, copy_size);
|
||||
|
||||
size -= copy_size;
|
||||
c += copy_size;
|
||||
|
||||
if (size == 0) {
|
||||
return NXT_OK;
|
||||
}
|
||||
if (free_size < size
|
||||
&& nxt_port_mmap_increase_buf(task, b, size, 1) == NXT_OK)
|
||||
{
|
||||
free_size = nxt_buf_mem_free_size(&b->mem);
|
||||
}
|
||||
} while (nxt_port_mmap_increase_buf(task, b, size, 1) == NXT_OK);
|
||||
}
|
||||
|
||||
if (free_size > 0) {
|
||||
copy_size = nxt_min(free_size, size);
|
||||
|
||||
b->mem.free = nxt_cpymem(b->mem.free, c, copy_size);
|
||||
|
||||
size -= copy_size;
|
||||
c += copy_size;
|
||||
|
||||
if (size == 0) {
|
||||
return NXT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
msg->buf = &b->next;
|
||||
}
|
||||
|
||||
@@ -255,11 +255,12 @@ fail:
|
||||
|
||||
static nxt_port_mmap_handler_t *
|
||||
nxt_port_new_port_mmap(nxt_task_t *task, nxt_process_t *process,
|
||||
nxt_port_t *port, nxt_bool_t tracking)
|
||||
nxt_port_t *port, nxt_int_t n, nxt_bool_t tracking)
|
||||
{
|
||||
void *mem;
|
||||
u_char *p, name[64];
|
||||
nxt_fd_t fd;
|
||||
nxt_int_t i;
|
||||
nxt_free_map_t *free_map;
|
||||
nxt_port_mmap_t *port_mmap;
|
||||
nxt_port_mmap_header_t *hdr;
|
||||
@@ -366,7 +367,9 @@ nxt_port_new_port_mmap(nxt_task_t *task, nxt_process_t *process,
|
||||
/* Mark first chunk as busy */
|
||||
free_map = tracking ? hdr->free_tracking_map : hdr->free_map;
|
||||
|
||||
nxt_port_mmap_set_chunk_busy(free_map, 0);
|
||||
for (i = 0; i < n; i++) {
|
||||
nxt_port_mmap_set_chunk_busy(free_map, i);
|
||||
}
|
||||
|
||||
/* Mark as busy chunk followed the last available chunk. */
|
||||
nxt_port_mmap_set_chunk_busy(hdr->free_map, PORT_MMAP_CHUNK_COUNT);
|
||||
@@ -456,7 +459,7 @@ nxt_port_mmap_get(nxt_task_t *task, nxt_port_t *port, nxt_chunk_id_t *c,
|
||||
/* TODO introduce port_mmap limit and release wait. */
|
||||
|
||||
*c = 0;
|
||||
mmap_handler = nxt_port_new_port_mmap(task, process, port, tracking);
|
||||
mmap_handler = nxt_port_new_port_mmap(task, process, port, n, tracking);
|
||||
|
||||
unlock_return:
|
||||
|
||||
@@ -710,10 +713,7 @@ nxt_port_mmap_increase_buf(nxt_task_t *task, nxt_buf_t *b, size_t size,
|
||||
|
||||
size -= free_size;
|
||||
|
||||
nchunks = size / PORT_MMAP_CHUNK_SIZE;
|
||||
if ((size % PORT_MMAP_CHUNK_SIZE) != 0 || nchunks == 0) {
|
||||
nchunks++;
|
||||
}
|
||||
nchunks = (size + PORT_MMAP_CHUNK_SIZE - 1) / PORT_MMAP_CHUNK_SIZE;
|
||||
|
||||
c = start;
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ struct nxt_port_mmap_tracking_msg_s {
|
||||
nxt_chunk_id_t tracking_id; /* Tracking index. */
|
||||
};
|
||||
|
||||
static nxt_bool_t
|
||||
nxt_inline nxt_bool_t
|
||||
nxt_port_mmap_get_free_chunk(nxt_free_map_t *m, nxt_chunk_id_t *c);
|
||||
|
||||
#define nxt_port_mmap_get_chunk_busy(m, c) \
|
||||
@@ -126,7 +126,7 @@ nxt_port_mmap_chunk_start(nxt_port_mmap_header_t *hdr, nxt_chunk_id_t c)
|
||||
}
|
||||
|
||||
|
||||
static nxt_bool_t
|
||||
nxt_inline nxt_bool_t
|
||||
nxt_port_mmap_get_free_chunk(nxt_free_map_t *m, nxt_chunk_id_t *c)
|
||||
{
|
||||
const nxt_free_map_t default_mask = (nxt_free_map_t) -1;
|
||||
|
||||
Reference in New Issue
Block a user