ircd/tout.cpp
#include "tout.hpp"
#include <assert.h>
ToutQueue::ToutQueue(): head(NULL), tail(NULL) {
}
ToutQueue::~ToutQueue() {
if (!head) return;
LOG("timeouts still pending");
do {
tout_node_t* node = head;
head = head->next;
pool.push(node);
} while (head);
}
bool ToutQueue::empty() const {
return (head == NULL);
}
void ToutQueue::push(int fd, time_t now) {
tout_node_t* node = pool.pop();
assert(!fds[fd]);
fds[fd] = node;
node->fd = fd;
node->at = now;
node->next = NULL;
if (!tail) {
node->prev = NULL;
head = tail = node;
} else {
assert(tail->at <= node->at);
node->prev = tail;
tail->next = node;
tail = node;
}
}
int ToutQueue::pop(time_t tout) {
if (!head || head->at >= tout) {
return -1;
}
tout_node_t* node = head;
head = head->next;
if (head) {
head->prev = NULL;
} else {
tail = NULL;
}
int fd = node->fd;
pool.push(node);
fds[fd] = NULL;
return fd;
}
void ToutQueue::pop(int fd) {
tout_node_t* node = fds[fd];
assert(node);
if (node == tail) {
tail = node->prev;
} else {
node->next->prev = node->prev;
}
if (node == head) {
head = node->next;
} else {
node->prev->next = node->next;
}
pool.push(node);
fds[fd] = NULL;
}