/* * Signal that no more work will be added to the queue. * NB: This function can be called when there are still tasks to process! * We're just saying that we're done adding new tasks. * TODO: This needs synchronization! */ void workq_finish(workq_t* workq) { workq_lock(workq); workq->done = 1; workq_unlock(workq); }
/* * Add work to the queue * TODO: This needs synchronization! */ void workq_put(workq_t* workq, void* data) { workq_lock(workq); task_t* task = (task_t*) malloc(sizeof(task_t)); task->data = data; task->next = workq->tasks; workq->tasks = task; workq_unlock(workq); }
/* * Get a data item from the queue. We assume NULL data can be used * to signal that the queue is empty. * TODO: This needs synchronization! */ void* workq_get(workq_t* workq) { void* result = NULL; if (workq->tasks) { workq_lock(&(workq)); task_t* task = workq->tasks; result = task->data; workq->tasks = task->next; free(task); workq_unlock(&(workq)); } return result; }
/* * Get a data item from the queue. We assume NULL data can be used * to signal that the queue is empty. * TODO: This needs synchronization! */ void* workq_get(workq_t* workq) { void* result = NULL; workq_lock(workq); workq_wait(workq); if (workq->tasks) { task_t* task = workq->tasks; result = task->data; workq->tasks = task->next; free(task); } workq_unlock(workq); return result; }