summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2017-09-18 17:35:24 +0300
committerMax Romanov <max.romanov@nginx.com>2017-09-18 17:35:24 +0300
commit4f7e00ef34345235f3b118749b5183a3f1ad5732 (patch)
treea0db28819ec6c3b03cc8f50d48e4c72814488b53
parent75a63256563a1eaf13fbd182800070849c3beb52 (diff)
downloadunit-4f7e00ef34345235f3b118749b5183a3f1ad5732.tar.gz
unit-4f7e00ef34345235f3b118749b5183a3f1ad5732.tar.bz2
Fixing shared memory thread safety issue.
Do not reuse shared memory segment with different port until this segment successfully received and indexed on other side. However, segment can be used to transfer data via the port it was sent at any time.
-rw-r--r--src/go/unit/nxt_go_port_memory.c5
-rw-r--r--src/go/unit/nxt_go_process.c2
-rw-r--r--src/nxt_port_memory.c7
-rw-r--r--src/nxt_port_memory_int.h1
4 files changed, 13 insertions, 2 deletions
diff --git a/src/go/unit/nxt_go_port_memory.c b/src/go/unit/nxt_go_port_memory.c
index c2a63a42..d2c0a0aa 100644
--- a/src/go/unit/nxt_go_port_memory.c
+++ b/src/go/unit/nxt_go_port_memory.c
@@ -106,6 +106,7 @@ nxt_go_new_port_mmap(nxt_go_process_t *process, nxt_port_id_t id)
hdr->id = process->outgoing.nelts - 1;
hdr->pid = process->pid;
+ hdr->sent_over = id;
/* Mark first chunk as busy */
nxt_port_mmap_set_chunk_busy(hdr, 0);
@@ -174,7 +175,9 @@ nxt_go_port_mmap_get(nxt_go_process_t *process, nxt_port_id_t port_id,
while (port_mmap < end_port_mmap) {
- if (nxt_port_mmap_get_free_chunk(port_mmap->hdr, c)) {
+ if ( (port_mmap->hdr->sent_over == 0xFFFFu ||
+ port_mmap->hdr->sent_over == port_id) &&
+ nxt_port_mmap_get_free_chunk(port_mmap->hdr, c)) {
hdr = port_mmap->hdr;
goto unlock_return;
diff --git a/src/go/unit/nxt_go_process.c b/src/go/unit/nxt_go_process.c
index c2b2c01c..736177ea 100644
--- a/src/go/unit/nxt_go_process.c
+++ b/src/go/unit/nxt_go_process.c
@@ -142,6 +142,8 @@ nxt_go_new_incoming_mmap(nxt_pid_t pid, nxt_fd_t fd)
port_mmap->hdr->id, process->incoming.nelts - 1);
}
+ port_mmap->hdr->sent_over = 0xFFFFu;
+
fail:
nxt_go_mutex_unlock(&process->incoming_mutex);
diff --git a/src/nxt_port_memory.c b/src/nxt_port_memory.c
index 82d96004..ec4bbdf7 100644
--- a/src/nxt_port_memory.c
+++ b/src/nxt_port_memory.c
@@ -198,6 +198,8 @@ nxt_port_incoming_port_mmap(nxt_task_t *task, nxt_process_t *process,
nxt_abort();
}
+ hdr->sent_over = 0xFFFFu;
+
fail:
nxt_thread_mutex_unlock(&process->incoming_mutex);
@@ -297,6 +299,7 @@ nxt_port_new_port_mmap(nxt_task_t *task, nxt_process_t *process,
hdr->id = process->outgoing->nelts - 1;
hdr->pid = process->pid;
+ hdr->sent_over = port->id;
/* Mark first chunk as busy */
nxt_port_mmap_set_chunk_busy(hdr, 0);
@@ -356,7 +359,9 @@ nxt_port_mmap_get(nxt_task_t *task, nxt_port_t *port, nxt_chunk_id_t *c,
while (port_mmap < end_port_mmap) {
- if (nxt_port_mmap_get_free_chunk(port_mmap->hdr, c)) {
+ if ( (port_mmap->hdr->sent_over == 0xFFFFu ||
+ port_mmap->hdr->sent_over == port->id) &&
+ nxt_port_mmap_get_free_chunk(port_mmap->hdr, c)) {
hdr = port_mmap->hdr;
goto unlock_return;
diff --git a/src/nxt_port_memory_int.h b/src/nxt_port_memory_int.h
index d82b6237..3c6c6ac6 100644
--- a/src/nxt_port_memory_int.h
+++ b/src/nxt_port_memory_int.h
@@ -49,6 +49,7 @@ typedef nxt_atomic_uint_t nxt_free_map_t;
struct nxt_port_mmap_header_s {
uint32_t id;
nxt_pid_t pid; /* For sanity check. */
+ nxt_port_id_t sent_over;
nxt_free_map_t free_map[MAX_FREE_IDX];
};