commits
tags
#include "queue.h"
#include <string.h>
#include "util.h"
void queue_init(Queue *q) {
memset(q, 0, sizeof(*q));
q->count = 0;
q->next_id = 1;
pthread_mutex_init(&q->lock, NULL);
}
static int find_index_locked(Queue *q, int id) {
for (int i = 0; i < q->count; i++) {
if (q->items[i].id == id) return i;
}
return -1;
}
int queue_add(Queue *q, const char *url, const char *title, const char *subdir) {
pthread_mutex_lock(&q->lock);
if (q->count >= MAX_QUEUE_ITEMS) {
pthread_mutex_unlock(&q->lock);
return -1;
}
QueueItem *item = &q->items[q->count++];
memset(item, 0, sizeof(*item));
item->id = q->next_id++;
safe_strcpy(item->url, sizeof(item->url), url);
safe_strcpy(item->title, sizeof(item->title), title);
safe_strcpy(item->subdir, sizeof(item->subdir), subdir);
item->status = STATUS_PENDING;
int id = item->id;
pthread_mutex_unlock(&q->lock);
return id;
}
int queue_get(Queue *q, int id, QueueItem *out) {
pthread_mutex_lock(&q->lock);
int idx = find_index_locked(q, id);
int found = 0;
if (idx >= 0) {
*out = q->items[idx];
found = 1;
}
pthread_mutex_unlock(&q->lock);
return found;
}
void queue_set_status(Queue *q, int id, ItemStatus status, const char *error) {
pthread_mutex_lock(&q->lock);
int idx = find_index_locked(q, id);
if (idx >= 0) {
q->items[idx].status = status;
if (error) safe_strcpy(q->items[idx].error, sizeof(q->items[idx].error), error);
if (status == STATUS_DONE) q->items[idx].percent = 100.0f;
}
pthread_mutex_unlock(&q->lock);
}
void queue_set_progress(Queue *q, int id, float percent, const char *speed, const char *eta) {
pthread_mutex_lock(&q->lock);
int idx = find_index_locked(q, id);
if (idx >= 0) {
q->items[idx].percent = percent;
safe_strcpy(q->items[idx].speed, sizeof(q->items[idx].speed), speed);
safe_strcpy(q->items[idx].eta, sizeof(q->items[idx].eta), eta);
}
pthread_mutex_unlock(&q->lock);
}
void queue_reset_for_retry(Queue *q, int id) {
pthread_mutex_lock(&q->lock);
int idx = find_index_locked(q, id);
if (idx >= 0) {
q->items[idx].status = STATUS_PENDING;
q->items[idx].percent = 0.0f;
q->items[idx].error[0] = '\0';
q->items[idx].speed[0] = '\0';
q->items[idx].eta[0] = '\0';
}
pthread_mutex_unlock(&q->lock);
}
static void remove_index_locked(Queue *q, int idx) {
for (int i = idx; i < q->count - 1; i++) {
q->items[i] = q->items[i + 1];
}
q->count--;
}
void queue_remove(Queue *q, int id) {
pthread_mutex_lock(&q->lock);
int idx = find_index_locked(q, id);
if (idx >= 0 && q->items[idx].status != STATUS_DOWNLOADING) {
remove_index_locked(q, idx);
}
pthread_mutex_unlock(&q->lock);
}
int queue_clear_finished(Queue *q) {
pthread_mutex_lock(&q->lock);
int removed = 0;
for (int i = 0; i < q->count; /* no increment here */) {
/* Only successfully finished items are cleared automatically;
* errored ones stay visible so they can be inspected/retried. */
ItemStatus s = q->items[i].status;
if (s == STATUS_DONE) {
remove_index_locked(q, i);
removed++;
} else {
i++;
}
}
pthread_mutex_unlock(&q->lock);
return removed;
}