add scheduler using libevent
diff --git a/include/event-scheduler.h b/include/event-scheduler.h
new file mode 100644
index 0000000..72169d8
--- /dev/null
+++ b/include/event-scheduler.h
@@ -0,0 +1,137 @@
+#ifndef EVENT_SCHEDULER_H
+#define EVENT_SCHEDULER_H
+#include <event2/event.h>
+#include <event2/event_struct.h>
+#include <event2/thread.h>
+
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/variate_generator.hpp>
+#include <boost/exception/all.hpp>
+#include <math.h>
+#include <multimap>
+
+#define _OVERRIDE
+#ifdef __GNUC__
+#if __GNUC_MAJOR >= 4 && __GNUC_MINOR__ >= 7
+  #undef _OVERRIDE
+  #define _OVERRIDE override
+#endif // __GNUC__ version
+#endif // __GNUC__
+
+using namespace std;
+
+
+class Task
+{
+public:
+  typedef boost::function<void (void *)> Callback;
+  typedef string Tag;
+  typedef boost::function<bool (const Task &task)> TaskMatcher;
+
+  Task(const Callback &callback, void *arg, const Tag &tag);
+  Task(const Task &other);
+  Task &
+  operator=(const Task &other);
+
+  virtual void
+  run() { m_callback(m_arg); }
+
+  Tag
+  tag() { return m_tag; }
+
+
+protected:
+  Callback m_callback;
+  Tag m_tag;
+  void *arg;
+};
+
+struct SchedulerException : virtual boost::exception, virtual exception { };
+
+class IntervalGenerator;
+typedef boost::shared_ptr<IntervalGenerator> IntervalGeneratorPtr;
+class Scheduler
+{
+public:
+  Scheduler();
+  virtual ~Scheduler();
+
+  virtual void
+  start();
+
+  virtual void
+  shutdown();
+
+  virtual void
+  addTask(const Task &task, double delay);
+
+  virtual void
+  addTimeoutTask(const Task &task, double timeout);
+
+  virtual void
+  addPeriodicTask(const Task &task, const IntervalGeneratorPtr &generator);
+
+  virtual void
+  deleteTask(const Tag &tag);
+
+  virtual void
+  deleteTask(const TaskMatcher &matcher);
+
+protected:
+  typedef multimap<Tag, Task> TaskMap;
+  TaskMap m_taskMap;
+};
+
+class IntervalGenerator
+{
+public:
+  virtual double
+  nextInterval() = 0;
+};
+
+class SimpleIntervalGenerator : IntervalGenerator
+{
+public:
+  SimpleIntervalGenerator(double interval) : m_interval(interval) {}
+  ~SimpleIntervalGenerator(){}
+  virtual double
+  nextInterval() _OVERRIDE { return m_interval; }
+private:
+  SimpleIntervalGenerator(const SimpleIntervalGenerator &other){};
+private:
+  double m_interval;
+};
+
+class RandomIntervalGenerator : IntervalGenerator
+{
+  typedef enum
+  {
+    UP,
+    DOWN,
+    EVEN
+  } Direction;
+
+public:
+  RandomIntervalGenerator(double interval, double percent, Direction direction = EVEN);
+  ~RandomIntervalGenerator(){}
+  virtual double
+  nextInterval() _OVERRIDE;
+
+private:
+  RandomIntervalGenerator(const RandomIntervalGenerator &other){};
+  inline double fractional(double x) { double dummy; return abs(modf(x, &dummy)); }
+
+private:
+  typedef boost::mt19937 RNG_TYPE;
+  RNG_TYPE m_rng;
+  boost::uniform_real<> m_dist;
+  boost::rariate_generator<RNG_TYPE &, boost::uniform_real<> > m_random;
+  Direction m_direction;
+  double m_interval;
+  double m_percent;
+
+};
+#endif // EVENT_SCHEDULER_H
diff --git a/src/event-scheduler.cpp b/src/event-scheduler.cpp
new file mode 100644
index 0000000..b823255
--- /dev/null
+++ b/src/event-scheduler.cpp
@@ -0,0 +1,49 @@
+#include "event-scheduler.h"
+
+Task::Task(const Callback &callback, void *arg, const Tag &tag)
+     : m_callback(callback)
+     , m_arg(arg)
+     , m_tag(tag)
+{
+}
+
+Task::Task(const Task &other)
+     : m_callback(other.m_callback)
+     , m_arg(other.m_arg)
+     , m_tag(other.m_tag)
+{
+}
+
+Task &
+Task::operator=(const Task &other)
+{
+  m_callback = other.m_callback;
+  m_arg = other.m_arg;
+  m_tag = other.m_tag;
+  return (*this);
+}
+
+RandomIntervalGenerator::RandomIntervalGenerator(double interval, double percent, Direction direction = UP)
+                        : m_interval(interval)
+                        , m_rng(time(NULL))
+                        , m_percent(percent)
+                        , m_dist(0.0, fractional(percent))
+                        , m_random(m_rng, m_dist)
+{
+}
+
+double
+RandomIntervalGenerator::nextInterval()
+{
+  double percent = m_random();
+  double interval = m_interval;
+  switch (m_direction)
+  {
+  case UP: interval = m_interval * (1.0 + percent); break;
+  case DOWN: interval = m_interval * (1.0 - percent); break;
+  case EVEN: interval = m_interval * (1.0 - m_percent/2.0 + percent); break;
+  default: break
+  }
+
+  return interval;
+}