queue: Allow direct appending to parent queues

This commit is contained in:
Thiago de Arruda 2015-09-01 09:58:30 -03:00
parent 2a0ff9f5cf
commit 203a4d5650

View File

@ -105,16 +105,15 @@ static Queue *queue_new(Queue *parent, put_callback put_cb, void *data)
void queue_free(Queue *queue) void queue_free(Queue *queue)
{ {
assert(queue); assert(queue);
if (queue->parent) { while (!QUEUE_EMPTY(&queue->headtail)) {
while (!QUEUE_EMPTY(&queue->headtail)) { QUEUE *q = QUEUE_HEAD(&queue->headtail);
QUEUE *q = QUEUE_HEAD(&queue->headtail); QueueItem *item = queue_node_data(q);
QueueItem *item = queue_node_data(q); if (queue->parent) {
assert(!item->link);
QUEUE_REMOVE(&item->data.item.parent->node); QUEUE_REMOVE(&item->data.item.parent->node);
xfree(item->data.item.parent); xfree(item->data.item.parent);
QUEUE_REMOVE(q);
xfree(item);
} }
QUEUE_REMOVE(q);
xfree(item);
} }
xfree(queue); xfree(queue);
@ -128,9 +127,8 @@ Event queue_get(Queue *queue)
void queue_put_event(Queue *queue, Event event) void queue_put_event(Queue *queue, Event event)
{ {
assert(queue); assert(queue);
assert(queue->parent); // don't push directly to the parent queue
queue_push(queue, event); queue_push(queue, event);
if (queue->parent->put_cb) { if (queue->parent && queue->parent->put_cb) {
queue->parent->put_cb(queue->parent, queue->parent->data); queue->parent->put_cb(queue->parent, queue->parent->data);
} }
} }
@ -177,11 +175,11 @@ static Event queue_remove(Queue *queue)
rv = child->data.item.event; rv = child->data.item.event;
xfree(child); xfree(child);
} else { } else {
assert(queue->parent); if (queue->parent) {
assert(!queue_empty(queue->parent)); // remove the corresponding link node in the parent queue
// remove the corresponding link node in the parent queue QUEUE_REMOVE(&item->data.item.parent->node);
QUEUE_REMOVE(&item->data.item.parent->node); xfree(item->data.item.parent);
xfree(item->data.item.parent); }
rv = item->data.item.event; rv = item->data.item.event;
} }
@ -195,11 +193,13 @@ static void queue_push(Queue *queue, Event event)
item->link = false; item->link = false;
item->data.item.event = event; item->data.item.event = event;
QUEUE_INSERT_TAIL(&queue->headtail, &item->node); QUEUE_INSERT_TAIL(&queue->headtail, &item->node);
// push link node to the parent queue if (queue->parent) {
item->data.item.parent = xmalloc(sizeof(QueueItem)); // push link node to the parent queue
item->data.item.parent->link = true; item->data.item.parent = xmalloc(sizeof(QueueItem));
item->data.item.parent->data.queue = queue; item->data.item.parent->link = true;
QUEUE_INSERT_TAIL(&queue->parent->headtail, &item->data.item.parent->node); item->data.item.parent->data.queue = queue;
QUEUE_INSERT_TAIL(&queue->parent->headtail, &item->data.item.parent->node);
}
} }
static QueueItem *queue_node_data(QUEUE *q) static QueueItem *queue_node_data(QUEUE *q)