1 
2 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /* vim: set ts=2 et sw=2 tw=80: */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
6  * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 // Original author: ekr@rtfm.com
9 #include <iostream>
10 
11 #include "nsThreadUtils.h"
12 #include "nsXPCOM.h"
13 
14 // nrappkit includes
15 extern "C" {
16 #include "nr_api.h"
17 #include "async_timer.h"
18 }
19 
20 #include "runnable_utils.h"
21 
22 #define GTEST_HAS_RTTI 0
23 #include "gtest/gtest.h"
24 #include "gtest_utils.h"
25 
26 using namespace mozilla;
27 
28 namespace {
29 
30 class TimerTest : public MtransportTest {
31  public:
TimerTest()32   TimerTest() : MtransportTest(), handle_(nullptr), fired_(false) {}
33   virtual ~TimerTest() = default;
34 
ArmTimer(int timeout)35   int ArmTimer(int timeout) {
36     int ret;
37 
38     test_utils_->sts_target()->Dispatch(
39         WrapRunnableRet(&ret, this, &TimerTest::ArmTimer_w, timeout),
40         NS_DISPATCH_SYNC);
41 
42     return ret;
43   }
44 
ArmCancelTimer(int timeout)45   int ArmCancelTimer(int timeout) {
46     int ret;
47 
48     test_utils_->sts_target()->Dispatch(
49         WrapRunnableRet(&ret, this, &TimerTest::ArmCancelTimer_w, timeout),
50         NS_DISPATCH_SYNC);
51 
52     return ret;
53   }
54 
ArmTimer_w(int timeout)55   int ArmTimer_w(int timeout) {
56     return NR_ASYNC_TIMER_SET(timeout, cb, this, &handle_);
57   }
58 
ArmCancelTimer_w(int timeout)59   int ArmCancelTimer_w(int timeout) {
60     int r;
61     r = ArmTimer_w(timeout);
62     if (r) return r;
63 
64     return CancelTimer_w();
65   }
66 
CancelTimer()67   int CancelTimer() {
68     int ret;
69 
70     test_utils_->sts_target()->Dispatch(
71         WrapRunnableRet(&ret, this, &TimerTest::CancelTimer_w),
72         NS_DISPATCH_SYNC);
73 
74     return ret;
75   }
76 
CancelTimer_w()77   int CancelTimer_w() { return NR_async_timer_cancel(handle_); }
78 
Schedule()79   int Schedule() {
80     int ret;
81 
82     test_utils_->sts_target()->Dispatch(
83         WrapRunnableRet(&ret, this, &TimerTest::Schedule_w), NS_DISPATCH_SYNC);
84 
85     return ret;
86   }
87 
Schedule_w()88   int Schedule_w() {
89     NR_ASYNC_SCHEDULE(cb, this);
90 
91     return 0;
92   }
93 
cb(NR_SOCKET r,int how,void * arg)94   static void cb(NR_SOCKET r, int how, void* arg) {
95     std::cerr << "Timer fired " << std::endl;
96 
97     TimerTest* t = static_cast<TimerTest*>(arg);
98 
99     t->fired_ = true;
100   }
101 
102  protected:
103   void* handle_;
104   bool fired_;
105 };
106 }  // namespace
107 
TEST_F(TimerTest,SimpleTimer)108 TEST_F(TimerTest, SimpleTimer) {
109   ArmTimer(100);
110   ASSERT_TRUE_WAIT(fired_, 1000);
111 }
112 
TEST_F(TimerTest,CancelTimer)113 TEST_F(TimerTest, CancelTimer) {
114   ArmTimer(1000);
115   CancelTimer();
116   PR_Sleep(2000);
117   ASSERT_FALSE(fired_);
118 }
119 
TEST_F(TimerTest,CancelTimer0)120 TEST_F(TimerTest, CancelTimer0) {
121   ArmCancelTimer(0);
122   PR_Sleep(100);
123   ASSERT_FALSE(fired_);
124 }
125 
TEST_F(TimerTest,ScheduleTest)126 TEST_F(TimerTest, ScheduleTest) {
127   Schedule();
128   ASSERT_TRUE_WAIT(fired_, 1000);
129 }
130