-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsockpuppet_todo_test.cpp
116 lines (96 loc) · 2.72 KB
/
sockpuppet_todo_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "sockpuppet/socket_async.h"
#include <chrono> // for std::chrono::steady_clock
#include <cstdlib> // for EXIT_SUCCESS
#include <iomanip> // for std::setw
#include <iostream> // for std::cout
using namespace sockpuppet;
static Driver driver;
static auto startTime = Clock::now();
std::ostream &operator<<(std::ostream &os, TimePoint tp)
{
using namespace std::chrono;
auto msecSinceStart = duration_cast<milliseconds>(tp - startTime);
os << std::setw(4) << msecSinceStart.count() << "ms";
return os;
}
void ScheduledPrint(char const *what, TimePoint expected)
{
std::cout << std::setw(10) << what
<< "; was scheduled for " << expected
<< "; now is " << Clock::now()
<< std::endl;
}
struct Repeatable
{
ToDo todo; // ToDo is stored for access with Shift/Cancel
Duration interval;
TimePoint next;
Repeatable(Duration interval, TimePoint until)
: todo(driver,
std::bind(&Repeatable::OnTime, this),
interval) // schedule first execution
, interval(interval)
, next(Clock::now() + interval)
{
// schedule own ToDo cancellation
ToDo(driver,
std::bind(&Repeatable::Cancel, this),
until);
}
void OnTime()
{
auto now = next;
next += interval;
// reschedule to run again at next interval
todo.Shift(interval);
ScheduledPrint("repeating", now);
}
void Cancel()
{
// everything is running in one thread;
// there is no danger of race conditions
// between OnTime and Cancel
todo.Cancel();
}
};
void Shutdown(TimePoint expected)
{
ScheduledPrint("shutdown", expected);
driver.Stop();
}
int main(int, char **)
try {
auto now = Clock::now();
// schedule-and-forget task; no need to store the created object
(void)ToDo(driver,
std::bind(ScheduledPrint,
"once",
now + Duration(50)),
Duration(50));
// rescheduling task that cancels itself eventually
Repeatable repeating(Duration(200),
now + Duration(1500));
// task that is scheduled conditionally after
// being created unscheduled
ToDo maybe(driver,
std::bind(ScheduledPrint,
"maybe",
now + Duration(150)));
if(true) {
maybe.Shift(now + Duration(150));
}
// schedule task to shut down eventually
ToDo(driver,
std::bind(Shutdown,
now + Duration(2000)),
Duration(2000));
// use the different driver loop methods
driver.Step(Duration(0));
driver.Step(Duration(150));
driver.Step(Duration(-1));
driver.Run();
return EXIT_SUCCESS;
} catch (std::exception const &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}