Logo Search packages:      
Sourcecode: mswatch version File versions  Download package

timeout_calc.cc

#include <algorithm>

#include "timeout_calc.h"

using std::min;
using std::max;


timeout_calc::timeout_calc(time_t base, time_t inter, time_t max)
    : default_inter_delay(inter),
      base_delay(base), inter_delay(inter),
      oldest_event(0), prev_dequeue(0),
      error_base_delay(inter), error_max_delay(max),
      is_error(false), error_delay(error_base_delay), error_ntries(0)
{ }

timeout_calc::timeout_calc(const mswatch_config& config)
    : default_inter_delay(config.default_inter_delay), 
      base_delay(config.base_delay), inter_delay(config.default_inter_delay),
      oldest_event(0), prev_dequeue(0),
      error_base_delay(config.default_inter_delay), error_max_delay(config.max_delay),
      is_error(false), error_delay(error_base_delay), error_ntries(0)
{ }


time_t timeout_calc::get_timeout() const
{
      time_t delay;

      if (!oldest_event)
            return -1;

      if (!is_error)
      {
            if (!prev_dequeue || oldest_event - prev_dequeue >= inter_delay)
                  delay = base_delay;
            else
                  delay = inter_delay - (oldest_event - prev_dequeue);
      }
      else
      {
            delay = error_delay;
      }

      return std::max(0L, delay - (time(NULL) - oldest_event));
}

void timeout_calc::enqueue_event()
{
      enqueue_event(default_inter_delay);
}

void timeout_calc::enqueue_event(time_t id)
{
      if (!oldest_event)
      {
            oldest_event = time(NULL);
            inter_delay = id;
      }
      else if (id < inter_delay)
      {
            // Switch to id and now if they timeout sooner
            time_t existing_oe = oldest_event;
            time_t existing_id = inter_delay;
            time_t existing_timeout = get_timeout();
            oldest_event = time(NULL);
            inter_delay = id;
            if (get_timeout() >= existing_timeout)
            {
                  oldest_event = existing_oe;
                  inter_delay = existing_id;
            }
      }
}

void timeout_calc::dequeue_events()
{
      inter_delay = default_inter_delay;
      oldest_event = 0;
      prev_dequeue = time(NULL);

      is_error = false;
      error_delay = error_base_delay;
      error_ntries = 0;
}

void timeout_calc::set_dequeue_error()
{
      is_error = true;
      oldest_event = time(NULL);
      error_ntries++;

      if (error_delay < error_max_delay)
      {
            if (error_ntries % 2 == 0)
                  error_delay = std::min(error_max_delay, 2 * error_delay);
      }
}

bool timeout_calc::get_dequeue_error() const
{
      return is_error;
}

Generated by  Doxygen 1.6.0   Back to index