-
Notifications
You must be signed in to change notification settings - Fork 10
/
ev_io.c
146 lines (132 loc) · 3.5 KB
/
ev_io.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
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
#include "ev_loop.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#define MINEVENTNUMBER 1024
int ev_io_init(ev_loop_t *loop, int max_ev_num, int etmodel) {
/* set a default minumum num of evnets*/
if (max_ev_num < MINEVENTNUMBER) {
max_ev_num = MINEVENTNUMBER;
}
loop->maxevent = max_ev_num;
loop->io_cnt = 0;
loop->etmodel = etmodel;
loop->events = (struct epoll_event *)malloc(max_ev_num * sizeof(struct epoll_event));
if (loop->events == NULL) {
fprintf(stderr, "No enough memory for loop->events\n");
return -1;
}
loop->iomap = (ev_io_t *)malloc(max_ev_num * sizeof(ev_io_t));
if (loop->iomap == NULL) {
fprintf(stderr, "No enough memory for loop->iomap\n");
return -1;
}
int i;
for (i = 0; i < max_ev_num; i++) {
loop->iomap[i].active = 0;
loop->iomap[i].events = 0;
loop->iomap[i].cb_read = NULL;
loop->iomap[i].cb_write = NULL;
loop->iomap[i].ptr = NULL;
}
return 0;
}
int ev_io_register(ev_loop_t* loop, int fd, EV_TYPE events, cb_io_t cb, void *ptr) {
if (fd >= loop->maxevent) {
return -1;
}
if (!(events & EV_READ || events & EV_WRITE)) {
fprintf(stderr, "invalid events\n");
return -1;
}
if (fd < 0) {
fprintf(stderr, "invalid fd:%d\n", fd);
return -1;
}
if (ptr != NULL) {
loop->iomap[fd].ptr = ptr;
}
/* events registerd already, just change the cb */
if ((loop->iomap[fd].events & events) == events) {
if (loop->iomap[fd].events & EV_READ) {
loop->iomap[fd].cb_read = cb;
}
if (loop->iomap[fd].events & EV_WRITE) {
loop->iomap[fd].cb_write = cb;
}
}
/* new events going to be added */
else {
if (EV_READ & events) {
loop->iomap[fd].cb_read = cb;
}
if (EV_WRITE & events) {
loop->iomap[fd].cb_write = cb;
}
loop->iomap[fd].events |= events;
struct epoll_event ev;
ev.events = loop->iomap[fd].events;
if (loop->etmodel) {
ev.events |= EPOLLET;
}
ev.data.fd = fd;
if(loop->iomap[fd].active) {/*mod*/
if(-1 == epoll_ctl(loop->epfd, EPOLL_CTL_MOD, fd, &ev)) {
fprintf(stderr, "ERROR: epoll_ctl mod in ev_register: %s\n", strerror(errno));
ev_io_clear(loop, fd);
return -1;
}
}
else {/*add*/
if(-1 == epoll_ctl(loop->epfd, EPOLL_CTL_ADD, fd, &ev)) {
fprintf(stderr, "ERROR: epoll_ctl add in ev_register: %s\n", strerror(errno));
ev_io_unregister(loop, fd);
return -1;
}
loop->io_cnt++;
}
}
loop->iomap[fd].active = 1;
return 0;
}
int ev_io_unregister(ev_loop_t* loop, int fd) {
struct epoll_event ev;
if (-1 == epoll_ctl(loop->epfd, EPOLL_CTL_DEL, fd, &ev)) {
fprintf(stderr, "ERROR: epoll_ctl del in ev_unregister: %s\n", strerror(errno));
ev_io_clear(loop, fd);
return -1;
}
ev_io_clear(loop, fd);
return 0;
}
int ev_io_stop(ev_loop_t* loop, int fd, EV_TYPE events) {
if (loop->iomap[fd].active && (loop->iomap[fd].events & events)) {
loop->iomap[fd].events &= (~events);
struct epoll_event ev;
ev.events = loop->iomap[fd].events;
if (loop->etmodel) {
ev.events |= EPOLLET;
}
ev.data.fd = fd;
if (-1 == epoll_ctl(loop->epfd, EPOLL_CTL_MOD, fd, &ev)) {
fprintf(stderr, "ERROR: epoll_ctl mod in ev_stop: %s\n", strerror(errno));
ev_io_clear(loop, fd);
return -1;
}
}
return 0;
}
int ev_io_clear(ev_loop_t *loop, int fd) {
loop->io_cnt--;
loop->iomap[fd].active = 0;
loop->iomap[fd].cb_read = NULL;
loop->iomap[fd].cb_write = NULL;
loop->iomap[fd].ptr = NULL;
return 0;
}