struct ctdb_queue {
struct ctdb_context *ctdb;
struct ctdb_partial partial; /* partial input packet */
- struct ctdb_queue_pkt *out_queue;
- /* This field is used to track the last added item so we
- can append new items to the end cheaply.
- This relies of that items are always appended to the tail
- and that when reamoving items we only remove the head.
- */
- struct ctdb_queue_pkt *out_queue_last_added;
+ struct ctdb_queue_pkt *out_queue, *out_queue_tail;
uint32_t out_queue_length;
struct fd_event *fde;
int fd;
if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
if (pkt->length != pkt->full_length) {
/* partial packet sent - we have to drop it */
- DLIST_REMOVE(queue->out_queue, pkt);
+ TLIST_REMOVE(queue->out_queue, queue->out_queue_tail,
+ pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
return;
}
- DLIST_REMOVE(queue->out_queue, pkt);
+ TLIST_REMOVE(queue->out_queue, queue->out_queue_tail, pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
EVENT_FD_WRITEABLE(queue->fde);
}
- /* This relies on that when adding items to the queue, we always add
- them to the tail and that when removing items we only remove
- the head of queue item.
- The last_added item thus allows non n^2 behaviour when appending to
- very long queues.
- */
- if (queue->out_queue == NULL) {
- DLIST_ADD(queue->out_queue, pkt);
- } else {
- DLIST_ADD_END(queue->out_queue_last_added, pkt, struct ctdb_queue_pkt *);
- }
- queue->out_queue_last_added = pkt;
+ TLIST_ADD_END(queue->out_queue, queue->out_queue_tail, pkt);
+
queue->out_queue_length++;
if (queue->ctdb->tunable.verbose_memory_names != 0) {