Add TimerHandler to event loop

Change-Id: I85c9142bcff9bf2cc5b8d003d24b8d77567fbe4a
diff --git a/aos/common/time.cc b/aos/common/time.cc
index e8bd25b..0fe3ee3 100644
--- a/aos/common/time.cc
+++ b/aos/common/time.cc
@@ -98,6 +98,22 @@
       chrono::duration_cast<chrono::nanoseconds>(offset).count();
 }
 
+struct timespec to_timespec(
+    const ::aos::monotonic_clock::duration duration) {
+  struct timespec time_timespec;
+  ::std::chrono::seconds sec =
+      ::std::chrono::duration_cast<::std::chrono::seconds>(duration);
+  ::std::chrono::nanoseconds nsec =
+      ::std::chrono::duration_cast<::std::chrono::nanoseconds>(duration - sec);
+  time_timespec.tv_sec = sec.count();
+  time_timespec.tv_nsec = nsec.count();
+  return time_timespec;
+}
+
+struct timespec to_timespec(
+    const ::aos::monotonic_clock::time_point time) {
+  return to_timespec(time.time_since_epoch());
+}
 }  // namespace time
 
 constexpr monotonic_clock::time_point monotonic_clock::min_time;
diff --git a/aos/common/time.h b/aos/common/time.h
index e541932..fe0bd5f 100644
--- a/aos/common/time.h
+++ b/aos/common/time.h
@@ -78,6 +78,13 @@
   DISALLOW_COPY_AND_ASSIGN(TimeFreezer);
 };
 
+// Converts a monotonic_clock::duration into a timespec object.
+struct timespec to_timespec(::aos::monotonic_clock::duration duration);
+
+// Converts a monotonic_clock::time_point into a timespec object as time since
+// epoch.
+struct timespec to_timespec(::aos::monotonic_clock::time_point time);
+
 }  // namespace time
 }  // namespace aos
 
diff --git a/aos/common/time_test.cc b/aos/common/time_test.cc
index 94102a2..14e049e 100644
--- a/aos/common/time_test.cc
+++ b/aos/common/time_test.cc
@@ -11,7 +11,6 @@
 namespace time {
 namespace testing {
 
-
 TEST(TimeTest, FromRate) {
   EXPECT_EQ(::std::chrono::milliseconds(10), FromRate(100));
 }
@@ -26,6 +25,30 @@
   EXPECT_LT(end - start, kSleepTime + ::std::chrono::milliseconds(200));
 }
 
+// Test to_timespec for a duration.
+TEST(TimeTest, DurationToTimespec) {
+  struct timespec pos_time = to_timespec(::std::chrono::milliseconds(56262));
+  EXPECT_EQ(pos_time.tv_sec, 56);
+  EXPECT_EQ(pos_time.tv_nsec, 262000000);
+
+  struct timespec neg_time = to_timespec(::std::chrono::milliseconds(-56262));
+  EXPECT_EQ(neg_time.tv_sec, -56);
+  EXPECT_EQ(neg_time.tv_nsec, -262000000);
+}
+
+// Test to_timespec for a time_point.
+TEST(TimeTest, TimePointToTimespec) {
+  struct timespec pos_time = to_timespec(::aos::monotonic_clock::epoch() +
+                                     ::std::chrono::seconds(1432423));
+  EXPECT_EQ(pos_time.tv_sec, 1432423);
+  EXPECT_EQ(pos_time.tv_nsec, 0);
+
+  struct timespec neg_time = to_timespec(::aos::monotonic_clock::epoch() -
+                                     ::std::chrono::seconds(1432423));
+  EXPECT_EQ(neg_time.tv_sec, -1432423);
+  EXPECT_EQ(neg_time.tv_nsec, 0);
+}
+
 }  // namespace testing
 }  // namespace time
 }  // namespace aos