Zadania rekrutacyjne i ćwiczeniowe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

95 lines
1.9 KiB

#include "thread/TaskQueue.h"
#include <stdlib.h>
inline static void runUntilEmpty(TaskQueuePtr queue) {
TaskEntry* current = NULL;
for (current = dequeueTask(queue);
current != NULL;
current = dequeueTask(queue)) {
if (queue->running) { // any task could've changed it
current->task(current->data);
}
freeTask(&current);
}
}
TaskQueuePtr createTaskQueue(BlockerHandle blocker, LockBlockerFn lock, NotifyBlockerFn notify)
{
TaskQueuePtr queue = calloc(1, sizeof(TaskQueue));
queue->front = NULL;
queue->back = NULL;
queue->blocker = blocker;
queue->lock = lock;
queue->notify = notify;
queue->running = false;
return queue;
}
void enqueueTask(TaskQueuePtr queue, Task task, void* data)
{
TaskEntry* newEntry = (TaskEntry*)calloc(1, sizeof(TaskEntry));
newEntry->task = task;
newEntry->data = data;
newEntry->next = NULL;
if (queue->front == NULL) {
queue->front = newEntry;
queue->back = newEntry;
} else {
queue->back->next = newEntry;
queue->back = newEntry;
}
queue->notify(queue->blocker);
}
TaskEntry* dequeueTask(TaskQueuePtr queue)
{
TaskEntry* current = NULL;
if (queue->front == NULL) {
return current;
}
current = queue->front;
queue->front = current->next;
if (queue->front == NULL) {
queue->back = NULL;
}
return current;
}
void runQueue(TaskQueuePtr queue)
{
queue->running = true;
while (queue->running) {
runUntilEmpty(queue);
if (queue->running) {
queue->lock(queue->blocker);
}
}
// execute remaining tasks
runUntilEmpty(queue);
}
void stopQueue(TaskQueuePtr queue)
{
queue->running = false;
queue->notify(queue->blocker);
}
void freeTask(TaskEntry** entry)
{
free(*entry);
*entry = NULL;
}
void freeTaskQueue(TaskQueuePtr* queue)
{
TaskEntry* task = dequeueTask(*queue);
while (task != NULL) {
freeTask(&task);
task = dequeueTask(*queue);
}
free(*queue);
*queue = NULL;
}