diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2020-10-19 21:37:38 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2020-10-20 11:51:48 -0400 |
commit | 6be2bd35a193c46a78b7db535a68f51707395a1e (patch) | |
tree | 4c2db05634a64b8cf3fc16aa5735d63392d76885 | |
parent | 7f8ab9dd292e1bbf5a031678bfddbd1476940f7b (diff) | |
download | lighttpd-git-6be2bd35a193c46a78b7db535a68f51707395a1e.tar.gz |
[core] FILE_CHUNK can hold stat_cache_entry ref
-rw-r--r-- | src/chunk.c | 32 | ||||
-rw-r--r-- | src/chunk.h | 2 |
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; |