sslbd/callout.hpp
#pragma once
#include "common.hpp"
#include "hooks.hpp"
#include "pool.hpp"
/** Periodically call some handler. Gets called from @see Poll */
class Periodic {
private:
static Periodic* inst;
Periodic() { assert(!inst); inst = this; }
typedef bool (*handler_t)(); // TODO: move timeout/wakeup out of poll into here?
typedef struct { handler_t h; unsigned i; time_t t; } periodic_t;
std::vector<periodic_t> periodic;
public:
static INLINE Periodic* getInst() { return inst ?: new Periodic(); }
static INLINE bool hasInst() { return inst != NULL; }
INLINE ~Periodic() { assert(inst == this); inst = NULL; }
void add(handler_t, unsigned); ///< for a few handlers (very inperformant for many handlers) that should be called every specific interval
bool del(handler_t); ///< also costly operation for removing a handler again
void run();
};
/** From a thread, enqueue some handler to be called synchronously. Gets called from @see Poll */
class WakeUp {
public:
typedef void (*handler_t)(void*);
private:
static WakeUp* inst;
WakeUp(): wakeups(NULL), lock(0) { assert(!inst); inst = this; }
typedef struct wakeup_s { handler_t h; void* ctx; struct wakeup_s* next; } wakeup_t;
TPool<wakeup_t> pool;
wakeup_t* wakeups;
atomic_t lock;
public:
static INLINE WakeUp* getInst() { return inst ?: new WakeUp(); }
INLINE ~WakeUp() { assert(inst == this); run(); inst = NULL; }
void add(handler_t, void*); ///< threadsafe
void run();
};
/** Gets called everytime from @see Poll */
class Poller {
public:
typedef bool (*handler_t)(void*); ///< gets called as long as it returns true
private:
static Poller* inst;
Poller(): pollers(NULL) { assert(!inst); inst = this; }
typedef struct poller_s { handler_t h; void* ctx; struct poller_s* next; } poller_t;
TPool<poller_t> pool;
poller_t* pollers;
public:
static INLINE Poller* getInst() { return inst ?: new Poller(); }
INLINE ~Poller();
void add(handler_t, void*);
bool del(handler_t, void*); ///< costly operation, must not be called when already running
void run();
};