-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTimeoutGuard.cpp
75 lines (65 loc) · 1.51 KB
/
TimeoutGuard.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
#include "stdafx.h"
#include "TimeoutGuard.h"
namespace utility
{
TimeoutGuard::TimeoutGuard(
clock::duration timeout,
std::function<void( void )> alarm,
clock::duration naptime
)
: timeout( timeout )
, alarm( alarm )
, naptime( naptime )
{
guard_thread = std::thread( std::bind( &TimeoutGuard::guard, this ) );
}
TimeoutGuard::TimeoutGuard(
clock::duration timeout,
std::function<void( void )> alarm
)
: TimeoutGuard( timeout, alarm, timeout )
{};
TimeoutGuard::~TimeoutGuard()
{
live.store( false );
wakeup.notify_all();
guard_thread.join();
}
void TimeoutGuard::guard()
{
while ( live.load() )
{
if ( idle.load() )
{
// Sleep indefinitely until either told to become active or destruct
std::unique_lock<std::mutex> live_lock( guard_mutex );
wakeup.wait( live_lock, [this]() { return ! this->idle.load() || ! this->live.load(); } );
};
// quit the loop if destructing
if ( ! live.load() ) break;
// the actual timeout checking
auto now = clock::now();
if ( ( now - touched.load() ) > timeout )
{
idle.store( true );
alarm();
continue; // skip waiting for next timeout
}
{
// sleep until next timeout check or destruction
std::unique_lock<std::mutex> live_lock( guard_mutex );
wakeup.wait_for( live_lock, naptime, [this](){ return ! this->live.load(); } );
}
};
}
void TimeoutGuard::watch()
{
touch();
idle.store( false );
wakeup.notify_all();
}
void TimeoutGuard::touch()
{
touched.store( clock::now() );
}
}