forked from wangyu-/UDPspeeder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelay_manager.cpp
135 lines (115 loc) · 2.69 KB
/
delay_manager.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* delay_manager.cpp
*
* Created on: Sep 15, 2017
* Author: root
*/
#include "delay_manager.h"
#include "log.h"
#include "packet.h"
int delay_data_t::handle()
{
return my_send(dest,data,len)>=0;
}
delay_manager_t::delay_manager_t()
{
capacity=0;
//if ((timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0)
//{
// mylog(log_fatal,"timer_fd create error");
// myexit(1);
//}
//itimerspec zero_its;
//memset(&zero_its, 0, sizeof(zero_its));
//timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &zero_its, 0);
}
delay_manager_t::~delay_manager_t()
{
//TODO ,we currently dont need to deconstruct it
}
/*
int delay_manager_t::get_timer_fd()
{
return timer_fd;
}*/
//int add(my_time_t delay,const dest_t &dest,const char *data,int len);
int delay_manager_t::add(my_time_t delay,const dest_t &dest,char *data,int len)
{
delay_data_t delay_data;
delay_data.dest=dest;
//delay_data.data=data;
delay_data.len=len;
if(capacity!=0&&int(delay_mp.size()) >=capacity)
{
mylog(log_warn,"max pending packet reached,ignored\n");
return -1;
}
if(delay==0)
{
static char buf[buf_len];
delay_data.data=buf;
memcpy(buf,data,len);
int ret=delay_data.handle();
if (ret != 0) {
mylog(log_trace, "handle() return %d\n", ret);
}
return 0;
}
delay_data_t tmp=delay_data;
tmp.data=(char *)malloc(delay_data.len+100);
if(!tmp.data)
{
mylog(log_warn, "malloc() returned null in delay_manager_t::add()");
return -1;
}
memcpy(tmp.data,data,delay_data.len);
my_time_t tmp_time=get_current_time_us();
tmp_time+=delay;
delay_mp.insert(make_pair(tmp_time,tmp));
////check(); check everytime when add, is it better ??
return 0;
}
int delay_manager_t::check()
{
if(!delay_mp.empty())
{
my_time_t current_time;
multimap<my_time_t,delay_data_t>::iterator it;
while(1)
{
int ret=0;
it=delay_mp.begin();
if(it==delay_mp.end()) break;
current_time=get_current_time_us();
if(it->first <= current_time)
{
ret=it->second.handle();
if (ret != 0) {
mylog(log_trace, "handle() return %d\n", ret);
}
free(it->second.data);
delay_mp.erase(it);
}
else
{
break;
}
}
if(!delay_mp.empty())
{
//itimerspec its;
//memset(&its.it_interval,0,sizeof(its.it_interval));
//its.it_value.tv_sec=delay_mp.begin()->first/1000000llu;
//its.it_value.tv_nsec=(delay_mp.begin()->first%1000000llu)*1000llu;
//timerfd_settime(timer_fd,TFD_TIMER_ABSTIME,&its,0);
ev_timer_stop(loop, &timer);
ev_timer_set(&timer, delay_mp.begin()->first /1000000.0 - ev_now(loop),0 ); //we should use ev_now here.
ev_timer_start(loop, &timer);
}
else
{
ev_timer_stop(loop, &timer); //not necessary
}
}
return 0;
}