-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtimer_manager.h
159 lines (122 loc) · 3.29 KB
/
timer_manager.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
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
158
159
/*
* timer_manager.h
*
* Created on: 2011-10-18
* Author: gxl2007@hotmail.com
*/
#ifndef TIMER_MANAGER_H_
#define TIMER_MANAGER_H_
#include <stdint.h>
#include <stdlib.h>
namespace xlnet
{
class timer_manager ;
/*
* @brief basic timer class , doubled linked
*/
class base_timer
{
friend class timer_manager ;
public:
base_timer() : m_next(NULL),m_prev(NULL),m_expired(0) { } ;
virtual ~base_timer() { if(m_prev && m_next) base_timer_remove(this);} ;
/*
* @brief get timer counter
*/
int64_t get_expired() const { return m_expired ;} ;
/*
* @brief set timer counter
* @param [in] timer counter
* @return 0 on sucess
*/
int set_expired(int64_t expired)
{
if(m_next || m_prev) return -1 ;
m_expired = expired;
return -1 ;
} ;
bool is_running() const { return (m_next || m_prev) ; } ;
protected:
/*
* @brief callback implemented by concrete class
* called when timer expired
*/
virtual void on_timeout(timer_manager* manager) { abort(); } ;
private:
static void base_timer_insert(base_timer* prev,base_timer* curr,base_timer* next);
static void base_timer_remove(base_timer* timer);
private:
base_timer* m_next ;
base_timer* m_prev ;
int64_t m_expired ;
} ;
template<typename T,void (T::*callback)(timer_manager* manager) =&T::on_timeout>
class template_timer : public base_timer
{
public:
explicit template_timer(T* owner = NULL ):m_owner(owner) { } ;
void set_owner(T* owner) { m_owner = owner ; } ;
protected:
virtual void on_timeout(timer_manager* manager) { (m_owner->*callback)(manager) ;} ;
private:
T* m_owner ;
};
class timer_manager
{
public:
public:
timer_manager() ;
~timer_manager();
public:
/*
* @brief initialize , alloc memory
* @param [in] time counter begin to run
* @param [in] slot bits
* @return 0 on success
*/
int init(int64_t start_time,int slot_bits) ;
void fini() ;
/*
* @brief insert timer
* @param [in] timer to be inserted
* @return 0 on success
*/
int add_timer(base_timer* timer) ;
/*
* @brief remove timer
* @param [in] timer
*/
void del_timer(base_timer* timer) ;
/*
* @brief call by main loop to run expired timers untill now
*/
void run_until(int64_t now) ;
int64_t get_curr_expired() const { return m_curr_expired ;} ;
/*
* @brief the latest timer counter to be expired
*/
int64_t get_next_expired() const { return m_next_expired ;} ;
int32_t get_max_timeout() const { return m_max_expired ; } ;
private:
enum
{
step_slot_min_bits = 3 ,
step_slot_max_bits = 20 ,
} ;
private:
timer_manager(const timer_manager& ) ;
timer_manager& operator=(const timer_manager&) ;
private:
base_timer *m_low_array ;
base_timer *m_high_array ;
int64_t m_curr_expired ;
int64_t m_next_expired ;
int8_t m_step_slot_bits ;
int16_t m_step_slot_size ;
int32_t m_step_slot_mask ;
int32_t m_max_expired ;
int32_t m_low_pos ;
int32_t m_high_pos ;
};
}
#endif /* TIMER_MANAGER_H_ */