|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|