diff options
Diffstat (limited to 'lib/sqfs/blk_proc')
-rw-r--r-- | lib/sqfs/blk_proc/pthread.c | 127 |
1 files changed, 34 insertions, 93 deletions
diff --git a/lib/sqfs/blk_proc/pthread.c b/lib/sqfs/blk_proc/pthread.c index de499f7..1c1088a 100644 --- a/lib/sqfs/blk_proc/pthread.c +++ b/lib/sqfs/blk_proc/pthread.c @@ -230,20 +230,6 @@ static void append_to_work_queue(sqfs_block_processor_t *proc, pthread_cond_broadcast(&proc->queue_cond); } -static sqfs_block_t *get_completed_if_avail(sqfs_block_processor_t *proc) -{ - sqfs_block_t *block = NULL; - - if (proc->done != NULL && - proc->done->sequence_number == proc->dequeue_id) { - block = proc->done; - proc->done = proc->done->next; - proc->dequeue_id += 1; - } - - return block; -} - static int test_and_set_status(sqfs_block_processor_t *proc, int status) { pthread_mutex_lock(&proc->mtx); @@ -308,26 +294,18 @@ static int process_done_queue(sqfs_block_processor_t *proc, sqfs_block_t *it, *block = NULL; int status = 0; - while (queue != NULL) { + while (queue != NULL && status == 0) { it = queue; queue = it->next; - it->next = NULL; if (it->flags & SQFS_BLK_IS_FRAGMENT) { + block = NULL; status = handle_fragment(proc, it, &block); - if (status != 0) { - free(it); - free(block); - free_blk_list(queue); - status = test_and_set_status(proc, status); - break; - } - - if (block != NULL) { + if (block != NULL && status == 0) { pthread_mutex_lock(&proc->mtx); proc->dequeue_id = it->sequence_number; - block->sequence_number = proc->dequeue_id; + block->sequence_number = it->sequence_number; if (proc->queue == NULL) { proc->queue = block; @@ -343,21 +321,17 @@ static int process_done_queue(sqfs_block_processor_t *proc, pthread_mutex_unlock(&proc->mtx); queue = NULL; + } else { + free(block); } } else { status = process_completed_block(proc, it); - - if (status != 0) { - status = test_and_set_status(proc, status); - free_blk_list(queue); - free(it); - break; - } } free(it); } + free_blk_list(queue); return status; } @@ -389,79 +363,46 @@ int sqfs_block_processor_enqueue(sqfs_block_processor_t *proc, queue = try_dequeue(proc); pthread_mutex_unlock(&proc->mtx); - return process_done_queue(proc, queue); + status = process_done_queue(proc, queue); + if (status != 0) + return test_and_set_status(proc, status); + + return 0; } int sqfs_block_processor_finish(sqfs_block_processor_t *proc) { - sqfs_block_t *it, *block; + sqfs_block_t *queue; int status = 0; - pthread_mutex_lock(&proc->mtx); -restart: - while (proc->backlog > 0 && proc->status == 0) - pthread_cond_wait(&proc->done_cond, &proc->mtx); + for (;;) { + pthread_mutex_lock(&proc->mtx); + while (proc->backlog > 0 && proc->status == 0) + pthread_cond_wait(&proc->done_cond, &proc->mtx); + + if (proc->status != 0) { + status = proc->status; + pthread_mutex_unlock(&proc->mtx); + return status; + } - if (proc->status != 0) { - status = proc->status; + queue = proc->done; + proc->done = NULL; pthread_mutex_unlock(&proc->mtx); - return status; - } - - while (proc->done != NULL) { - it = get_completed_if_avail(proc); - if (it == NULL) { - status = SQFS_ERROR_INTERNAL; - } else if (it->flags & SQFS_BLK_IS_FRAGMENT) { - block = NULL; - status = handle_fragment(proc, it, &block); - - if (status != 0) { - proc->status = status; - pthread_mutex_unlock(&proc->mtx); - free(block); - free(it); - return status; - } - - if (block != NULL) { - proc->dequeue_id = it->sequence_number; - block->sequence_number = proc->dequeue_id; - free(it); - - if (proc->queue == NULL) { - proc->queue = block; - proc->queue_last = block; - } else { - block->next = proc->queue; - proc->queue = block; - } - - proc->backlog += 1; - pthread_cond_broadcast(&proc->queue_cond); - goto restart; - } - - free(it); - } else { - status = process_completed_block(proc, it); - free(it); - - if (status != 0) { - proc->status = status; - pthread_mutex_unlock(&proc->mtx); - return status; + if (queue == NULL) { + if (proc->frag_block != NULL) { + append_to_work_queue(proc, proc->frag_block); + proc->frag_block = NULL; + continue; } + break; } - } - if (proc->frag_block != NULL) { - append_to_work_queue(proc, proc->frag_block); - proc->frag_block = NULL; - goto restart; + status = process_done_queue(proc, queue); + if (status != 0) + return status; } - pthread_mutex_unlock(&proc->mtx); return 0; } |