add some gross bucketing to implement a queue for freeing stream_info structs after an operation has completed (in library mode ONLY; no changes will occur during regular execution) to fix some leaks

This commit is contained in:
discomfitor 2011-08-13 03:35:36 -04:00 committed by Con Kolivas
parent 949c6d7a97
commit 63141a1035
3 changed files with 37 additions and 7 deletions

View file

@ -337,6 +337,10 @@ 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 : 1;

17
rzip.c
View file

@ -1117,9 +1117,18 @@ retry:
void rzip_control_free(rzip_control *control)
{
if (!control) return;
size_t x;
if (!control) return;
free(control->tmpdir);
if (control->suffix && control->suffix[0]) free(control->suffix);
free(control);
free(control->tmpdir);
free(control->outname);
free(control->outdir);
if (control->suffix && control->suffix[0]) free(control->suffix);
for (x = 0; x < control->sinfo_idx; x++) {
free(control->sinfo_queue[x]->s);
free(control->sinfo_queue[x]);
}
free(control->sinfo_queue);
free(control);
}

View file

@ -1797,11 +1797,28 @@ 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) 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) 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 because their values are read after the next
* stream has started so they're not properly freed and just dropped on
* program exit! FIXME */
/* 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.
*/
free(sinfo->s);
free(sinfo);
#endif