sslbd/callout.cpp
#include "callout.hpp"
HOOK(POST_IO, HOOK_PRIO_MID) {
delete Periodic::getInst();
delete WakeUp::getInst();
delete Poller::getInst();
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
Periodic* Periodic::inst = NULL;
void Periodic::run() {
for (std::vector<periodic_t>::iterator it = periodic.begin(); it != periodic.end();) {
log(io, "periodic handler %p in: %ld", it->h, it->t-NOW);
if (unlikely(it->t <= NOW)) {
if (it->h()) {
it->t = NOW + it->i;
++it;
} else {
it = periodic.erase(it);
}
} else {
++it;
}
}
}
void Periodic::add(handler_t h, unsigned i) {
(void)del(h);
periodic.push_back((periodic_t){ h, i, (time_t)(NOW+i) });
log(debug, "added %us periodic handler %p", i, h);
}
bool Periodic::del(handler_t h) {
for (std::vector<periodic_t>::iterator it = periodic.begin(); it != periodic.end(); ++it) {
if (it->h == h) {
periodic.erase(it);
log(debug, "removed periodic handler %p", h);
return true;
}
}
return false;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
WakeUp* WakeUp::inst = NULL;
void WakeUp::add(handler_t h, void* c) {
spin_lock(&lock);
wakeup_t* w = pool.pop();
w->h = h;
w->ctx = c;
w->next = wakeups;
wakeups = w;
spin_unlock(&lock);
}
void WakeUp::run() {
spin_lock(&lock);
wakeup_t* w = wakeups;
wakeups = NULL;
spin_unlock(&lock);
if (!w) return;
wakeup_t* i = w;
while (i) {
log(io, "wakeup handler %p(%p)", i->h, i->ctx);
i->h(i->ctx);
i = i->next;
}
spin_lock(&lock);
while (w) {
i = w->next;
pool.push(w);
w = i;
}
spin_unlock(&lock);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
Poller* Poller::inst = NULL;
Poller::~Poller() {
poller_t* p = pollers;
while (p) {
(void)p->h(p->ctx);
poller_t* tmp = p->next;
pool.push(p);
p = tmp;
}
}
void Poller::add(handler_t h, void* c) {
log(io, "add poll handler %p(%p)", h, c);
poller_t* p = pool.pop();
p->h = h;
p->ctx = c;
p->next = pollers;
pollers = p;
}
bool Poller::del(handler_t h, void* c) {
poller_t* prev = NULL;
poller_t* p = pollers;
while (p) {
if (p->h == h && p->ctx == c) {
if (prev) {
prev->next = p->next;
} else {
pollers = p->next;
}
pool.push(p);
return true;
} else {
prev = p;
p = p->next;
}
}
return false;
}
void Poller::run() {
poller_t* prev = NULL;
poller_t* p = pollers;
while (p) {
log(io, "poll handler %p(%p)", p->h, p->ctx);
if (!p->h(p->ctx)) {
poller_t* n = p->next;
if (prev) {
prev->next = n;
} else {
pollers = n;
}
pool.push(p);
p = n;
} else {
prev = p;
p = p->next;
}
}
}