forked from svarshavchik/vera
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproc_container_timer.C
157 lines (119 loc) · 3.22 KB
/
proc_container_timer.C
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
** Copyright 2022 Double Precision, Inc.
** See COPYING for distribution information.
*/
#include "config.h"
#include "proc_container_timer.H"
#include "proc_container.H"
#include "current_containers_info.H"
#include "log.H"
#include <iostream>
#include <map>
static current_timers_t current_timers;
proc_container_timerObj::proc_container_timerObj(
const current_containers_info &all_containers,
const proc_container &container,
time_t time_start,
time_t time_end,
const std::function<void (const current_containers_callback_info &
)> &done
) : my_iter{current_timers.end()}, time_start{time_start}, time_end{time_end},
all_containers(all_containers), container{container}, done{done}
{
}
proc_container_timerObj::~proc_container_timerObj()
{
if (my_iter != current_timers.end())
current_timers.erase(my_iter);
}
void update_timer_containers(const current_containers &new_current_containers)
{
for (auto &[alarm, wtimer] : current_timers)
{
auto timer=wtimer.lock();
if (!timer)
continue;
auto old_container=timer->container.lock();
if (!old_container)
continue;
auto iter=new_current_containers.find(old_container);
if (iter != new_current_containers.end())
timer->container=iter->first;
}
}
proc_container_timer create_timer(
const current_containers_info &all_containers,
const proc_container &container,
time_t timeout,
const std::function<void (const current_containers_callback_info &
)> &done
)
{
time_t time_start=log_current_timespec().tv_sec;
time_t time_end=time_start+timeout;
auto timer=std::make_shared<proc_container_timerObj>(
all_containers, container, time_start, time_end, done
);
if (timeout == 0)
return timer; // Pretend there's a timeout, but there's not.
auto iter=current_timers.emplace(time_end, timer);
timer->my_iter=iter;
return timer;
}
int run_timers()
{
bool ran_something=false;
while (1)
{
auto b=current_timers.begin();
if (b == current_timers.end())
break;
const auto &now=log_current_timespec();
if (b->first > now.tv_sec)
{
if (ran_something)
return 0;
// Compute the delay in whole seconds
int ms = (b->first-now.tv_sec < 60
? b->first-now.tv_sec:60)*1000;
if (!proc_container_inprogress().empty() &&
ms > 1000)
{
// Update verbose progress indication once a
// second.
ms=1000;
}
// Subtract the milliseconds that already elapsed in
// this fraction of a second.
int sub = now.tv_nsec / 1000000;
// The delay must be at least 1 second or 1000 ms,
// when we get here.
//
// So the fractional second here cannot really exceed
// this, this is more of a sanity check.
if (sub < ms)
ms -= sub;
return ms;
}
auto timer=b->second.lock();
current_timers.erase(b);
if (!timer)
continue; // Shouldn't happen
timer->my_iter=current_timers.end();
auto me=timer->all_containers.lock();
auto pc=timer->container.lock();
if (!me || !pc)
continue;
current_containers_callback_info info{me};
info.cc=me->containers.find(pc);
if (info.cc == me->containers.end())
continue;
timer->done(info);
// We might find something to do.
me->find_start_or_stop_to_do();
ran_something=true;
}
if (ran_something)
return 0;
return -1;
}