forked from anqin/trident
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timer_worker.h
109 lines (84 loc) · 2.44 KB
/
timer_worker.h
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
// Copyright (c) 2014 The Trident Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
//
#ifndef _TRIDENT_TIMER_WORKER_H_
#define _TRIDENT_TIMER_WORKER_H_
#include <trident/common_internal.h>
namespace trident {
class TimerWorker : public trident::enable_shared_from_this<TimerWorker>
{
public:
typedef boost::function<void(const PTime& /* now */)> WorkRoutine;
public:
TimerWorker(IOService& io_service)
: _io_service(io_service)
, _is_running(false)
, _time_duration(time_duration_seconds(1))
, _work_routine(NULL)
, _timer(io_service)
, _strand(io_service)
{}
~TimerWorker()
{
TRIDENT_FUNCTION_TRACE;
stop();
}
bool is_running()
{
return _is_running;
}
void set_time_duration(const TimeDuration& time_duration)
{
_time_duration = time_duration;
}
void set_work_routine(const WorkRoutine& work_routine)
{
_work_routine = work_routine;
}
void start()
{
if (_is_running) return;
_is_running = true;
ScopedLocker<MutexLock> _(_timer_lock);
_timer.expires_from_now(_time_duration);
_timer.async_wait(_strand.wrap(boost::bind(
&TimerWorker::on_timeout, shared_from_this(), _1)));
}
void stop()
{
if (!_is_running) return;
_is_running = false;
ScopedLocker<MutexLock> _(_timer_lock);
_timer.cancel();
}
private:
void on_timeout(const boost::system::error_code& ec)
{
if (_is_running)
{
PTime now = ptime_now();
if (ec != boost::asio::error::operation_aborted && _work_routine)
{
_work_routine(now);
}
ScopedLocker<MutexLock> _(_timer_lock);
_timer.expires_at(now + _time_duration);
_timer.async_wait(_strand.wrap(boost::bind(
&TimerWorker::on_timeout, shared_from_this(), _1)));
}
}
private:
IOService& _io_service;
volatile bool _is_running;
TimeDuration _time_duration;
WorkRoutine _work_routine;
IOServiceTimer _timer;
MutexLock _timer_lock;
IOServiceStrand _strand;
TRIDENT_DISALLOW_EVIL_CONSTRUCTORS(TimerWorker);
}; // class TimerWorker
} // namespace trident
#endif // _TRIDENT_TIMER_WORKER_H_
/* vim: set ts=4 sw=4 sts=4 tw=100 */