Michael Hilbert
Michael Hilbert

Reputation: 256

Access to class data from handler for boost deadline_timer

I was able to create a handler for a boost deadline_time (which is a member) by declaring it static. Unfortunately this prevents the access to non-static member data.

I have a series of timeouts. So my idea was to have a single deadline_timer while maintaining an ordered list of timeout events. Every time the next timeout event would happen, the class would retrigger the timer with the next timeout event in the class calculating the remaining time for this timeout event.

For this concept to work the handler would need to manipulate non-static data. But this is not possible sence boost::asio requires a static handler.

Anybody got an idea how to handle this?

class TimerController {
public:
void setTimer(const eibaddr_t gad, const timesecs_t timedelay);  
void cancelTimer(const eibaddr_t gad);
bool isRunning(const eibaddr_t gad);
void setGad(const eibaddr_t gad);
static void timerHandler(const boost::system::error_code &ec); 
private:
boost::asio::deadline_timer* m_pTimer;
struct timerList_s
{
    eibaddr_t gad;
    boost::posix_time::ptime absTimeOut;
    timerList_s(const timerList_s& elem) : gad(elem.gad),
                                           absTimeOut(elem.absTimeOut)
    {
    };
    timerList_s(const eibaddr_t& pgad, const boost::posix_time::ptime pato) 
        : gad(pgad),
          absTimeOut(pato)
    {
    };
    timerList_s& operator= (const timerList_s& elem)
    {
        gad = elem.gad;
        absTimeOut = elem.absTimeOut;
        return *this;
    };
    bool operator< (const timerList_s& elem) const
    {
        return (absTimeOut < elem.absTimeOut);
    };
    bool operator== (const timerList_s& elem) const
    {
        return (gad == elem.gad);
    };
};
std::list<timerList_s> m_timers;

Upvotes: 1

Views: 582

Answers (2)

Sam Miller
Sam Miller

Reputation: 24174

I have a series of timeouts. So my idea was to have a single deadline_timer while maintaining an ordered list of timeout events. Every time the next timeout event would happen, the class would retrigger the timer with the next timeout event in the class calculating the remaining time for this timeout event.

this is a very odd design.

For this concept to work the handler would need to manipulate non-static data. But this is not possible sence boost::asio requires a static handler.

boost::asio does not require a static handler, see the documentation. It requires a handler with the signature

void handler(
  const boost::system::error_code& error // Result of operation.
);

The typical recipe here is to use boost::bind to bind a member function to the handler. The async TCP client example shows one way to do this. The author of the asio library has an excellent blog post describing this concept in detail if you have trouble understanding it.

Upvotes: 0

megabyte1024
megabyte1024

Reputation: 8660

It is possible to use the deadline_timer class with non-static data using boost::bind in the following way deadline_.async_wait(bind(&client::check_deadline, this));. Details available in ASIO's examples, for instance, here.

Upvotes: 3

Related Questions