95 |
95 |
96 for(;;) { |
96 for(;;) { |
97 /* wait for events */ |
97 /* wait for events */ |
98 int ret = epoll_wait(ep, events, 16, 100000); |
98 int ret = epoll_wait(ep, events, 16, 100000); |
99 if(ret == -1 && errno != EINTR) { |
99 if(ret == -1 && errno != EINTR) { |
100 /* TODO: check for error */ |
100 log_ereport(LOG_FAILURE, "epoll_wait failed: %s", strerror(errno)); |
101 perror("epoll_wait"); |
|
102 continue; |
101 continue; |
103 } |
102 } |
104 |
103 |
105 for(int i=0;i<ret;i++) { |
104 for(int i=0;i<ret;i++) { |
106 event_t *event = events[i].data.ptr; |
105 event_t *event = events[i].data.ptr; |
107 if(event->fn) { |
106 if(event->fn) { |
|
107 int saved_ev = event->poll; |
108 if(!event->fn(ev, event)) { |
108 if(!event->fn(ev, event)) { |
109 // event fn returned 0 -> remove event from epoll |
109 // event fn returned 0 -> remove event from epoll |
110 if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { |
110 if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { |
111 perror("epoll_ctl"); |
111 log_ereport( |
|
112 LOG_FAILURE, |
|
113 "epoll_ctl failed: %s", |
|
114 strerror(errno)); |
112 } |
115 } |
113 |
116 |
114 // if set, execute event->finish |
117 // if set, execute event->finish |
115 if(event->finish) { |
118 if(event->finish) { |
116 event->finish(ev, event); |
119 event->finish(ev, event); |
|
120 } |
|
121 } else { |
|
122 if(saved_ev != event->poll) { |
|
123 // event type changed |
|
124 struct epoll_event epev; |
|
125 epev.events = EPOLLET; |
|
126 epev.data.ptr = event; |
|
127 |
|
128 // adjust epoll events |
|
129 if((event->poll & EVENT_POLLIN) == EVENT_POLLIN) { |
|
130 epev.events |= EPOLLIN; |
|
131 } |
|
132 if((event->poll & EVENT_POLLOUT) == EVENT_POLLOUT) { |
|
133 epev.events |= EPOLLOUT; |
|
134 } |
|
135 |
|
136 if(epoll_ctl(ep, EPOLL_CTL_MOD, event->object, NULL)) { |
|
137 log_ereport( |
|
138 LOG_FAILURE, |
|
139 "epoll_wait failed: %s", |
|
140 strerror(errno)); |
|
141 } |
117 } |
142 } |
118 } |
143 } |
119 } |
144 } |
120 } |
145 } |
121 } |
146 } |
134 return h->ep[cp]; |
159 return h->ep[cp]; |
135 } |
160 } |
136 |
161 |
137 int ev_pollin(event_handler_t *h, int fd, event_t *event) { |
162 int ev_pollin(event_handler_t *h, int fd, event_t *event) { |
138 event->object = (intptr_t)fd; |
163 event->object = (intptr_t)fd; |
|
164 event->poll = EVENT_POLLIN; |
139 struct epoll_event epev; |
165 struct epoll_event epev; |
140 epev.events = EPOLLIN | EPOLLET; /* input event, edge triggered */ |
166 epev.events = EPOLLIN | EPOLLET; // input event, edge triggered |
141 epev.data.ptr = event; |
167 epev.data.ptr = event; |
142 return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); |
168 return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); |
143 } |
169 } |
144 |
170 |
145 int ev_pollout(event_handler_t *h, int fd, event_t *event) { |
171 int ev_pollout(event_handler_t *h, int fd, event_t *event) { |
146 event->object = (intptr_t)fd; |
172 event->object = (intptr_t)fd; |
|
173 event->poll = EVENT_POLLOUT; |
147 struct epoll_event epev; |
174 struct epoll_event epev; |
148 epev.events = EPOLLOUT | EPOLLET; /* input event, edge triggered */ |
175 epev.events = EPOLLOUT | EPOLLET; // input event, edge triggered |
149 epev.data.ptr = event; |
176 epev.data.ptr = event; |
150 return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); |
177 return epoll_ctl(ev_get_port(h), EPOLL_CTL_ADD, fd, &epev); |
151 } |
178 } |
152 |
179 |
153 int evt_send(event_handler_t *h, event_t *event) { |
180 int evt_send(event_handler_t *h, event_t *event) { |
154 event->object = 0; |
181 event->object = 0; |
155 // TODO: implement using threadpool |
182 // TODO: implement using threadpool or eventfd |
156 fprintf(stderr, "Warning: evt_send not implemented\n"); |
183 fprintf(stderr, "Warning: evt_send not implemented\n"); |
157 return 0; |
184 return 0; |
158 } |
185 } |