92 int ep = ev->ep; |
92 int ep = ev->ep; |
93 |
93 |
94 struct epoll_event events[EV_MAX_EVENTS]; |
94 struct epoll_event events[EV_MAX_EVENTS]; |
95 Event* finished[EV_MAX_EVENTS]; |
95 Event* finished[EV_MAX_EVENTS]; |
96 |
96 |
|
97 int loop_ctn = 0; |
97 for(;;) { |
98 for(;;) { |
98 /* wait for events */ |
99 /* wait for events */ |
99 int ret = epoll_wait(ep, events, 16, 100000); |
100 int ret = epoll_wait(ep, events, 16, EV_IDLE_TIMEOUT * 1000); |
100 if(ret == -1 && errno != EINTR) { |
101 if(ret == -1 && errno != EINTR) { |
101 log_ereport(LOG_FAILURE, "epoll_wait failed: %s", strerror(errno)); |
102 log_ereport(LOG_FAILURE, "epoll_wait failed: %s", strerror(errno)); |
102 continue; |
103 continue; |
103 } |
104 } |
104 |
105 |
105 int numfinished = 0; |
106 int numfinished = 0; |
106 ev->base.numret = 0; |
107 ev->base.numret = 0; |
107 for(int i=0;i<ret;i++) { |
108 for(int i=0;i<ret;i++) { |
108 Event *event = events[i].data.ptr; |
109 Event *event = events[i].data.ptr; |
109 if(!event) { |
110 if(!event) { |
181 // execute return calls |
182 // execute return calls |
182 for(int i=0;i<ev->base.numret;i++) { |
183 for(int i=0;i<ev->base.numret;i++) { |
183 EVReturn ret = ev->base.fnreturn[i]; |
184 EVReturn ret = ev->base.fnreturn[i]; |
184 nsapi_saf_return(ret.sn, ret.rq, ret.ret); |
185 nsapi_saf_return(ret.sn, ret.rq, ret.ret); |
185 } |
186 } |
|
187 |
|
188 if(ret == 0 || ++loop_ctn >= EV_IDLE_LOOP_CTN) { |
|
189 watchlist_check(&ev->base, 0); |
|
190 loop_ctn = 0; |
|
191 } |
186 } |
192 } |
187 } |
193 } |
188 |
194 |
189 int ev_convert2sys_events(int events) { |
195 int ev_convert2sys_events(int events) { |
190 int e = EPOLLET; |
196 int e = EPOLLET; |
200 int ev_pollin(EventHandler *h, int fd, Event *event) { |
206 int ev_pollin(EventHandler *h, int fd, Event *event) { |
201 EventHandlerLinux *ev = (EventHandlerLinux*)h; |
207 EventHandlerLinux *ev = (EventHandlerLinux*)h; |
202 event->object = (intptr_t)fd; |
208 event->object = (intptr_t)fd; |
203 event->events = EVENT_POLLIN; |
209 event->events = EVENT_POLLIN; |
204 struct epoll_event epev; |
210 struct epoll_event epev; |
205 epev.events = EPOLLIN | EPOLLET; // input event, edge triggered |
211 epev.events = EPOLLIN | EPOLLRDHUP | EPOLLET; // input event, edge triggered |
206 epev.data.ptr = event; |
212 epev.data.ptr = event; |
207 return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev); |
213 return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev); |
208 } |
214 } |
209 |
215 |
210 int ev_pollout(EventHandler *h, int fd, Event *event) { |
216 int ev_pollout(EventHandler *h, int fd, Event *event) { |
211 EventHandlerLinux *ev = (EventHandlerLinux*)h; |
217 EventHandlerLinux *ev = (EventHandlerLinux*)h; |
212 event->object = (intptr_t)fd; |
218 event->object = (intptr_t)fd; |
213 event->events = EVENT_POLLOUT; |
219 event->events = EVENT_POLLOUT; |
214 struct epoll_event epev; |
220 struct epoll_event epev; |
215 epev.events = EPOLLOUT | EPOLLET; // input event, edge triggered |
221 epev.events = EPOLLOUT | EPOLLRDHUP | EPOLLET; // input event, edge triggered |
216 epev.data.ptr = event; |
222 epev.data.ptr = event; |
217 return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev); |
223 return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev); |
218 } |
224 } |
219 |
225 |
220 int ev_remove_poll(EventHandler *h, int fd) { |
226 int ev_remove_poll(EventHandler *h, int fd) { |