mirror of
https://github.com/ckolivas/lrzip.git
synced 2025-12-06 07:12:00 +01:00
Deallocate runzip structures after all runzip chunks are complete to avoid a race in the case of a failed chunk decompressing.
This commit is contained in:
parent
2c7c4832b3
commit
be884d09e0
|
|
@ -356,6 +356,12 @@ struct node {
|
||||||
struct node *prev;
|
struct node *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct runzip_node {
|
||||||
|
struct stream_info *sinfo;
|
||||||
|
pthread_t *pthreads;
|
||||||
|
struct runzip_node *prev;
|
||||||
|
};
|
||||||
|
|
||||||
struct rzip_state {
|
struct rzip_state {
|
||||||
void *ss;
|
void *ss;
|
||||||
struct node *sslist;
|
struct node *sslist;
|
||||||
|
|
@ -468,6 +474,8 @@ struct rzip_control {
|
||||||
i64 (*match_len)(rzip_control *, struct rzip_state *, i64, i64, i64, i64 *);
|
i64 (*match_len)(rzip_control *, struct rzip_state *, i64, i64, i64, i64 *);
|
||||||
|
|
||||||
pthread_t *pthreads;
|
pthread_t *pthreads;
|
||||||
|
struct runzip_node *rulist;
|
||||||
|
struct runzip_node *ruhead;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uncomp_thread {
|
struct uncomp_thread {
|
||||||
|
|
|
||||||
19
runzip.c
19
runzip.c
|
|
@ -246,6 +246,21 @@ static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum,
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_rulist(rzip_control *control)
|
||||||
|
{
|
||||||
|
while (control->ruhead) {
|
||||||
|
struct runzip_node *node = control->ruhead;
|
||||||
|
struct stream_info *sinfo = node->sinfo;
|
||||||
|
|
||||||
|
dealloc(sinfo->ucthreads);
|
||||||
|
dealloc(node->pthreads);
|
||||||
|
dealloc(sinfo->s);
|
||||||
|
dealloc(sinfo);
|
||||||
|
control->ruhead = node->prev;
|
||||||
|
dealloc(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* decompress a section of an open file. Call fatal_return(() on error
|
/* decompress a section of an open file. Call fatal_return(() on error
|
||||||
return the number of bytes that have been retrieved
|
return the number of bytes that have been retrieved
|
||||||
*/
|
*/
|
||||||
|
|
@ -363,6 +378,10 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64
|
||||||
if (unlikely(close_stream_in(control, ss)))
|
if (unlikely(close_stream_in(control, ss)))
|
||||||
fatal("Failed to close stream!\n");
|
fatal("Failed to close stream!\n");
|
||||||
|
|
||||||
|
/* We can now safely delete sinfo and pthread data of all threads
|
||||||
|
* created. */
|
||||||
|
clear_rulist(control);
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
25
stream.c
25
stream.c
|
|
@ -1085,6 +1085,8 @@ void *open_stream_in(rzip_control *control, int f, int n, char chunk_bytes)
|
||||||
sinfo->s = calloc(sizeof(struct stream), n);
|
sinfo->s = calloc(sizeof(struct stream), n);
|
||||||
if (unlikely(!sinfo->s)) {
|
if (unlikely(!sinfo->s)) {
|
||||||
dealloc(sinfo);
|
dealloc(sinfo);
|
||||||
|
dealloc(threads);
|
||||||
|
dealloc(ucthreads);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1206,6 +1208,8 @@ again:
|
||||||
failed:
|
failed:
|
||||||
dealloc(sinfo->s);
|
dealloc(sinfo->s);
|
||||||
dealloc(sinfo);
|
dealloc(sinfo);
|
||||||
|
dealloc(threads);
|
||||||
|
dealloc(ucthreads);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1818,6 +1822,20 @@ int close_stream_out(rzip_control *control, void *ss)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add to an runzip list to safely deallocate memory after all threads have
|
||||||
|
* returned. */
|
||||||
|
static void add_to_rulist(rzip_control *control, struct stream_info *sinfo)
|
||||||
|
{
|
||||||
|
struct runzip_node *node = calloc(sizeof(struct runzip_node), 1);
|
||||||
|
|
||||||
|
if (unlikely(!node))
|
||||||
|
failure("Failed to calloc struct node in add_rulist\n");
|
||||||
|
node->sinfo = sinfo;
|
||||||
|
node->pthreads = control->pthreads;
|
||||||
|
node->prev = control->rulist;
|
||||||
|
control->ruhead = node;
|
||||||
|
}
|
||||||
|
|
||||||
/* close down an input stream */
|
/* close down an input stream */
|
||||||
int close_stream_in(rzip_control *control, void *ss)
|
int close_stream_in(rzip_control *control, void *ss)
|
||||||
{
|
{
|
||||||
|
|
@ -1834,10 +1852,9 @@ int close_stream_in(rzip_control *control, void *ss)
|
||||||
dealloc(sinfo->s[i].buf);
|
dealloc(sinfo->s[i].buf);
|
||||||
|
|
||||||
output_thread = 0;
|
output_thread = 0;
|
||||||
dealloc(sinfo->ucthreads);
|
/* We cannot safely release the sinfo and pthread data here till all
|
||||||
dealloc(control->pthreads);
|
* threads are shut down. */
|
||||||
dealloc(sinfo->s);
|
add_to_rulist(control, sinfo);
|
||||||
dealloc(sinfo);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue