summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2020-10-19 21:37:38 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2020-10-20 11:51:48 -0400
commit6be2bd35a193c46a78b7db535a68f51707395a1e (patch)
tree4c2db05634a64b8cf3fc16aa5735d63392d76885
parent7f8ab9dd292e1bbf5a031678bfddbd1476940f7b (diff)
downloadlighttpd-git-6be2bd35a193c46a78b7db535a68f51707395a1e.tar.gz
[core] FILE_CHUNK can hold stat_cache_entry ref
-rw-r--r--src/chunk.c32
-rw-r--r--src/chunk.h2
2 files changed, 26 insertions, 8 deletions
diff --git a/src/chunk.c b/src/chunk.c
index 3deaf4f3..f9d8a96f 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -100,7 +100,12 @@ static void chunk_reset_file_chunk(chunk *c) {
if (!chunk_buffer_string_is_empty(c->mem))
unlink(c->mem->ptr);
}
- if (c->file.fd != -1) {
+ if (c->file.refchg) {
+ c->file.refchg(c->file.ref, -1);
+ c->file.refchg = 0; /* NULL fn ptr */
+ c->file.ref = NULL;
+ }
+ else if (c->file.fd != -1) {
close(c->file.fd);
c->file.fd = -1;
}
@@ -472,6 +477,20 @@ void chunkqueue_set_tempdirs(chunkqueue * const restrict cq, const array * const
cq->tempdir_idx = 0;
}
+static void chunkqueue_steal_partial_file_chunk(chunkqueue * const restrict dest, const chunk * const restrict c, const off_t len) {
+ chunkqueue_append_file(dest, c->mem, c->offset, len);
+ if (c->file.fd >= 0) {
+ chunk * const d = dest->last;
+ if (c->file.refchg) {
+ d->file.ref = c->file.ref;
+ d->file.refchg = c->file.refchg;
+ d->file.refchg(d->file.ref, 1);
+ }
+ else
+ d->file.fd = fdevent_dup_cloexec(c->file.fd);
+ }
+}
+
void chunkqueue_steal(chunkqueue * const restrict dest, chunkqueue * const restrict src, off_t len) {
while (len > 0) {
chunk *c = src->first;
@@ -507,9 +526,7 @@ void chunkqueue_steal(chunkqueue * const restrict dest, chunkqueue * const restr
break;
case FILE_CHUNK:
/* tempfile flag is in "last" chunk after the split */
- chunkqueue_append_file(dest, c->mem, c->offset, use);
- if (c->file.fd >= 0)
- dest->last->file.fd = fdevent_dup_cloexec(c->file.fd);
+ chunkqueue_steal_partial_file_chunk(dest, c, use);
break;
}
@@ -583,6 +600,7 @@ int chunkqueue_append_mem_to_tempfile(chunkqueue * const restrict dest, const ch
if (dst_c->file.length >= (off_t)dest->upload_temp_file_size) {
/* the chunk is too large now, close it */
+ force_assert(0 == dst_c->file.refchg); /*(else should not happen)*/
int rc = close(dst_c->file.fd);
dst_c->file.fd = -1;
if (0 != rc) {
@@ -633,6 +651,7 @@ int chunkqueue_append_mem_to_tempfile(chunkqueue * const restrict dest, const ch
/*(remove empty chunk and unlink tempfile)*/
chunkqueue_remove_empty_chunks(dest);
} else {/*(close tempfile; avoid later attempts to append)*/
+ force_assert(0 == dst_c->file.refchg); /*(else should not happen)*/
int rc = close(dst_c->file.fd);
dst_c->file.fd = -1;
if (0 != rc) {
@@ -681,10 +700,7 @@ int chunkqueue_steal_with_tempfiles(chunkqueue * const restrict dest, chunkqueue
} else {
/* partial chunk with length "use" */
/* tempfile flag is in "last" chunk after the split */
- chunkqueue_append_file(dest, c->mem, c->offset, use);
- if (c->file.fd >= 0)
- dest->last->file.fd = fdevent_dup_cloexec(c->file.fd);
-
+ chunkqueue_steal_partial_file_chunk(dest, c, use);
c->offset += use;
force_assert(0 == len);
}
diff --git a/src/chunk.h b/src/chunk.h
index 87036fff..da2f01b4 100644
--- a/src/chunk.h
+++ b/src/chunk.h
@@ -38,6 +38,8 @@ typedef struct chunk {
size_t length; /* size of the mmap'ed area */
off_t offset; /* start is <n> octet away from the start of the file */
} mmap;
+ void *ref;
+ void(*refchg)(void *, int);
} file;
} chunk;