summaryrefslogtreecommitdiff
path: root/lib/sqfs/blk_proc/pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/blk_proc/pthread.c')
-rw-r--r--lib/sqfs/blk_proc/pthread.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/lib/sqfs/blk_proc/pthread.c b/lib/sqfs/blk_proc/pthread.c
index a3dc01f..4f01bb3 100644
--- a/lib/sqfs/blk_proc/pthread.c
+++ b/lib/sqfs/blk_proc/pthread.c
@@ -119,11 +119,17 @@ sqfs_block_processor_t *sqfs_block_processor_create(size_t max_block_size,
proc->cmp = cmp;
proc->file = file;
proc->max_blocks = INIT_BLOCK_COUNT;
+ proc->frag_list_max = INIT_BLOCK_COUNT;
proc->blocks = alloc_array(sizeof(proc->blocks[0]), proc->max_blocks);
if (proc->blocks == NULL)
goto fail_init;
+ proc->frag_list = alloc_array(sizeof(proc->frag_list[0]),
+ proc->frag_list_max);
+ if (proc->frag_list == NULL)
+ goto fail_init;
+
for (i = 0; i < num_workers; ++i) {
proc->workers[i] = alloc_flex(sizeof(compress_worker_t),
1, max_block_size);
@@ -172,6 +178,7 @@ fail_init:
pthread_cond_destroy(&proc->done_cond);
pthread_cond_destroy(&proc->queue_cond);
pthread_mutex_destroy(&proc->mtx);
+ free(proc->frag_list);
free(proc->fragments);
free(proc->blocks);
free(proc);
@@ -200,6 +207,8 @@ void sqfs_block_processor_destroy(sqfs_block_processor_t *proc)
free_blk_list(proc->queue);
free_blk_list(proc->done);
+ free(proc->frag_block);
+ free(proc->frag_list);
free(proc->fragments);
free(proc->blocks);
free(proc);
@@ -241,16 +250,40 @@ int sqfs_block_processor_enqueue(sqfs_block_processor_t *proc,
sqfs_block_t *completed = NULL;
int status;
- pthread_mutex_lock(&proc->mtx);
- if (proc->status != 0) {
- status = proc->status;
+ if (block->flags & ~SQFS_BLK_USER_SETTABLE_FLAGS) {
+ status = SQFS_ERROR_UNSUPPORTED;
+
+ pthread_mutex_lock(&proc->mtx);
+ if (proc->status == 0) {
+ proc->status = status;
+ pthread_cond_broadcast(&proc->queue_cond);
+ }
goto fail;
}
- if (block->flags & ~SQFS_BLK_USER_SETTABLE_FLAGS) {
- status = SQFS_ERROR_UNSUPPORTED;
- proc->status = status;
- pthread_cond_broadcast(&proc->queue_cond);
+ if (block->flags & SQFS_BLK_IS_FRAGMENT) {
+ block->checksum = crc32(0, block->data, block->size);
+
+ completed = NULL;
+ status = handle_fragment(proc, block, &completed);
+
+ if (status != 0) {
+ pthread_mutex_lock(&proc->mtx);
+ proc->status = status;
+ goto fail;
+ }
+
+ free(block);
+ if (completed == NULL)
+ return 0;
+
+ block = completed;
+ completed = NULL;
+ }
+
+ pthread_mutex_lock(&proc->mtx);
+ if (proc->status != 0) {
+ status = proc->status;
goto fail;
}
@@ -288,6 +321,11 @@ int sqfs_block_processor_finish(sqfs_block_processor_t *proc)
int status = 0;
pthread_mutex_lock(&proc->mtx);
+ if (proc->frag_block != NULL) {
+ append_to_work_queue(proc, proc->frag_block);
+ proc->frag_block = NULL;
+ }
+
while (proc->backlog > 0 && proc->status == 0)
pthread_cond_wait(&proc->done_cond, &proc->mtx);