mirror of
https://github.com/ckolivas/lrzip.git
synced 2026-01-11 11:00:05 +01:00
Create a linked list to safely release data which cannot be released earlier after all compression is complete and all compressionthreads have returned, fixing a minor leak.
This commit is contained in:
parent
9f544dc372
commit
96c7c62584
|
|
@ -351,8 +351,15 @@ struct checksum {
|
|||
|
||||
typedef i64 tag;
|
||||
|
||||
struct node {
|
||||
void *data;
|
||||
struct node *prev;
|
||||
};
|
||||
|
||||
struct rzip_state {
|
||||
void *ss;
|
||||
struct node *sslist;
|
||||
struct node *head;
|
||||
struct level *level;
|
||||
tag hash_index[256];
|
||||
struct hash_entry *hash_table;
|
||||
|
|
@ -444,10 +451,6 @@ struct rzip_control {
|
|||
const char *util_infile;
|
||||
char delete_infile;
|
||||
const char *util_outfile;
|
||||
#define STREAM_BUCKET_SIZE 20
|
||||
size_t sinfo_buckets;
|
||||
size_t sinfo_idx;
|
||||
struct stream_info **sinfo_queue;
|
||||
char delete_outfile;
|
||||
FILE *outputfile;
|
||||
char library_mode;
|
||||
|
|
|
|||
35
rzip.c
35
rzip.c
|
|
@ -872,6 +872,17 @@ init_sliding_mmap(rzip_control *control, struct rzip_state *st, int fd_in,
|
|||
sb->fd = fd_in;
|
||||
}
|
||||
|
||||
static void add_to_sslist(rzip_control *control, struct rzip_state *st)
|
||||
{
|
||||
struct node *node = calloc(sizeof(struct node), 1);
|
||||
|
||||
if (unlikely(!node))
|
||||
failure("Failed to calloc struct node in add_to_sslist\n");
|
||||
node->data = st->ss;
|
||||
node->prev = st->sslist;
|
||||
st->head = node;
|
||||
}
|
||||
|
||||
/* compress a chunk of an open file. Assumes that the file is able to
|
||||
be mmap'd and is seekable */
|
||||
static inline void
|
||||
|
|
@ -903,6 +914,23 @@ rzip_chunk(rzip_control *control, struct rzip_state *st, int fd_in, int fd_out,
|
|||
|
||||
if (unlikely(close_stream_out(control, st->ss)))
|
||||
failure("Failed to flush/close streams in rzip_chunk\n");
|
||||
|
||||
/* Save the sinfo data to a list to be safely released after all
|
||||
* threads have been shut down. */
|
||||
add_to_sslist(control, st);
|
||||
}
|
||||
|
||||
static void clear_sslist(struct rzip_state *st)
|
||||
{
|
||||
while (st->head) {
|
||||
struct node *node = st->head;
|
||||
struct stream_info *sinfo = node->data;
|
||||
|
||||
dealloc(sinfo->s);
|
||||
dealloc(sinfo);
|
||||
st->head = node->prev;
|
||||
dealloc(node);
|
||||
}
|
||||
}
|
||||
|
||||
/* compress a whole file chunks at a time */
|
||||
|
|
@ -1225,12 +1253,12 @@ retry:
|
|||
print_progress("Compression Ratio: %.3f. Average Compression Speed: %6.3fMB/s.\n",
|
||||
1.0 * s.st_size / s2.st_size, chunkmbs);
|
||||
|
||||
clear_sslist(st);
|
||||
dealloc(st);
|
||||
}
|
||||
|
||||
void rzip_control_free(rzip_control *control)
|
||||
{
|
||||
size_t x;
|
||||
if (!control)
|
||||
return;
|
||||
|
||||
|
|
@ -1240,10 +1268,5 @@ void rzip_control_free(rzip_control *control)
|
|||
if (control->suffix && control->suffix[0])
|
||||
dealloc(control->suffix);
|
||||
|
||||
for (x = 0; x < control->sinfo_idx; x++) {
|
||||
dealloc(control->sinfo_queue[x]->s);
|
||||
dealloc(control->sinfo_queue[x]);
|
||||
}
|
||||
dealloc(control->sinfo_queue);
|
||||
dealloc(control);
|
||||
}
|
||||
|
|
|
|||
33
stream.c
33
stream.c
|
|
@ -1812,37 +1812,12 @@ int close_stream_out(rzip_control *control, void *ss)
|
|||
for (i = 0; i < sinfo->num_streams; i++)
|
||||
rewrite_encrypted(control, sinfo, sinfo->s[i].last_headofs);
|
||||
}
|
||||
if (control->library_mode) {
|
||||
if (!control->sinfo_buckets) {
|
||||
/* no streams added */
|
||||
control->sinfo_queue = calloc(STREAM_BUCKET_SIZE + 1, sizeof(void*));
|
||||
if (!control->sinfo_queue) {
|
||||
print_err("Failed to calloc sinfo_queue in close_stream_out\n");
|
||||
return -1;
|
||||
}
|
||||
control->sinfo_buckets++;
|
||||
} else if (control->sinfo_idx == STREAM_BUCKET_SIZE * control->sinfo_buckets + 1) {
|
||||
/* all buckets full, create new bucket */
|
||||
void *tmp;
|
||||
|
||||
tmp = realloc(control->sinfo_queue, (++control->sinfo_buckets * STREAM_BUCKET_SIZE + 1) * sizeof(void*));
|
||||
if (!tmp) {
|
||||
print_err("Failed to realloc sinfo_queue in close_stream_out\n");
|
||||
return -1;
|
||||
}
|
||||
control->sinfo_queue = tmp;
|
||||
memset(control->sinfo_queue + control->sinfo_idx, 0, ((control->sinfo_buckets * STREAM_BUCKET_SIZE + 1) - control->sinfo_idx) * sizeof(void*));
|
||||
}
|
||||
control->sinfo_queue[control->sinfo_idx++] = sinfo;
|
||||
}
|
||||
#if 0
|
||||
/* These cannot be freed immediately because their values are read after the next
|
||||
* stream has started. Instead (in library mode), they are stored and only freed
|
||||
* after the entire operation has completed.
|
||||
/* Note that sinfo->s and sinfo are not released here but after compression
|
||||
* has completed as they cannot be freed immediately because their values
|
||||
* are read after the next stream has started.
|
||||
*/
|
||||
dealloc(sinfo->s);
|
||||
dealloc(sinfo);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue