-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.c
More file actions
138 lines (111 loc) · 2.58 KB
/
timer.c
File metadata and controls
138 lines (111 loc) · 2.58 KB
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
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "timer.h"
typedef struct node {
TimerId_t id; /* 唯一标识 */
int timeout; /* 超时值 */
int count; /* 计时器 */
void (*action)(void *arg); /* 超时行为 */
void *arg;
enum TimerType type; /* 闹钟类型 */
struct node *prev, *next;
}Timer_t;
Timer_t Head;
/**
* SIGALARM信号处理函数,检查闹钟任务是否有超时
* @signo: 信号标识
*/
static void sighandler(int signo);
/**
* 初始化Timer,成功返回0,失败返回-1
*/
int timer_init(void)
{
Head.next = &Head;
Head.prev = &Head;
if (signal(SIGALRM, sighandler) == SIG_ERR)
return -1;
alarm(1);
return 0;
}
/**
* 添加Timer,成功返回新添加的Timer标识,失败返回-1
* @sec: Timer触发的时间间隔
* @task: 绑定Timer的任务
* @arg: 任务传参
* @type: Timer类型
*/
TimerId_t timer_add(int sec, Task_t *task, void *arg, enum TimerType type)
{
Timer_t *one;
one = (Timer_t*)malloc(sizeof(Timer_t));
if(one == NULL)
return ADD_FAILED;
one->timeout = sec;
one->count = 0;
one->arg = arg;
one->action = task;
one->type = type;
one->id = (TimerId_t)one; /* 用节点地址作唯一标识 */
one->next = &Head;
one->prev = Head.prev;
one->next->prev = one;
one->prev->next = one;
return one->id;
}
/**
* 删除指定的闹钟
* @id:闹钟标识
*/
void timer_del(TimerId_t id)
{
Timer_t *i = Head.next;
while (i != &Head) {
if (i->id == id) {
i->prev->next = i->next;
i->next->prev = i->prev;
free(i);
break;
}
i = i->next;
}
}
/**
* 销毁所有闹钟
*/
void timer_destroy(void)
{
Timer_t *i, *n;
alarm(0);
signal(SIGALRM, SIG_DFL);
for (i = Head.next; i != &Head; i = n) {
n = i->next;
free(i);
}
}
/**
* 检查闹钟任务是否有超时
*/
static void sighandler(int signo)
{
Timer_t *i, *n;
if (signo != SIGALRM)
return;
for( i = Head.next; i != &Head; i = n) {
n = i->next;
i->count++;
if (i->count >= i->timeout) {
/* 闹钟时间到,执行设定好的任务 */
i->action(i->arg);
if (i->type == ONCE) {
i->prev->next = i->next;
i->next->prev = i->prev;
free(i);
} else {
i->count = 0;
}
}
}
alarm(1);
}