-
Notifications
You must be signed in to change notification settings - Fork 28
/
vn_event_timer.c
96 lines (78 loc) · 2.17 KB
/
vn_event_timer.c
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
/*
* Copyright (C) Chenyang Li
* Copyright (C) Vino
*/
#include <stdlib.h>
#include <sys/time.h>
#include "vn_event_timer.h"
#include "vn_priority_queue.h"
#include "vn_palloc.h"
#include "vn_logger.h"
#include "vn_error.h"
extern vn_priority_queue_t pq;
int vn_event_timer_init(void) {
vn_pq_init(&pq);
vn_event_time_update();
return 0;
}
void vn_event_time_update(void) {
struct timeval tv;
vn_sec_t sec;
vn_msec_t msec;
if (gettimeofday(&tv, NULL) < 0) {
err_sys("[vn_time_update] gettimeofday error");
}
sec = tv.tv_sec;
msec = tv.tv_usec / 1000;
vn_current_msec = sec * 1000 + msec;
}
vn_msec_t vn_event_find_timer(void) {
long timer;
vn_priority_queue_node_t *node;
if (vn_pq_isempty(&pq)) {
return 0;
}
node = vn_pq_min(&pq);
timer = node->key - vn_current_msec;
return timer > 0 ? timer : 0;
}
void vn_event_expire_timers(void) {
vn_priority_queue_node_t *node;
vn_http_connection_t *conn;
while (!vn_pq_isempty(&pq)) {
node = vn_pq_min(&pq);
if (node->deleted == VN_PQ_DELETED) {
vn_pq_delete_min(&pq);
continue;
}
/*
* If node.key < vn_current_msec, timeout.
* Be careful, the gap should be cast to Long type.
*/
if ((long) (node->key - vn_current_msec) > 0) {
return;
}
conn = (vn_http_connection_t *) node->data;
if (conn->handler) {
#ifdef DEBUG
DEBUG_PRINT("The timer has invoked handler to close the connection, [fd = %d]", conn->fd);
#endif
(*conn->handler)(conn);
}
vn_pq_delete_min(&pq);
}
}
void vn_event_add_timer(vn_http_connection_t *conn, vn_msec_t timer) {
vn_priority_queue_node_t *node;
vn_msec_t key;
if ((node = (vn_priority_queue_node_t *) vn_palloc(conn->pool, sizeof(vn_priority_queue_node_t))) == NULL) {
err_sys("[vn_event_add_timer] vn_palloc error");
}
vn_event_time_update();
key = vn_current_msec + timer;
node->key = key;
node->data = (void *) conn;
node->deleted = VN_PQ_NOT_DELETED;
vn_pq_insert(&pq, node);
conn->pq_node = node;
}