54 handler->ep = epoll_create(64); |
54 handler->ep = epoll_create(64); |
55 if(handler->ep == 0) { |
55 if(handler->ep == 0) { |
56 // TODO: error |
56 // TODO: error |
57 return NULL; |
57 return NULL; |
58 } |
58 } |
59 handler->eventfd = eventfd(0, 0); |
59 |
60 if(handler->eventfd == 0) { |
60 int eventpipe[2]; |
|
61 if(pipe(eventpipe)) { |
61 return NULL; |
62 return NULL; |
62 } |
63 } |
|
64 handler->eventin = eventpipe[0]; |
|
65 handler->eventout = eventpipe[1]; |
|
66 |
63 struct epoll_event epev; |
67 struct epoll_event epev; |
64 epev.events = EPOLLIN | EPOLLET; // input event, edge triggered |
68 epev.events = EPOLLIN | EPOLLET; // input event, edge triggered |
65 epev.data.ptr = NULL; |
69 epev.data.ptr = NULL; |
66 if(epoll_ctl(handler->ep, EPOLL_CTL_ADD, handler->eventfd, &epev)) { |
70 if(epoll_ctl(handler->ep, EPOLL_CTL_ADD, handler->eventin, &epev)) { |
67 return NULL; |
71 return NULL; |
68 } |
72 } |
69 |
73 |
70 SYS_THREAD t = systhread_start( |
74 SYS_THREAD t = systhread_start( |
71 0, |
75 0, |
94 } |
98 } |
95 |
99 |
96 for(int i=0;i<ret;i++) { |
100 for(int i=0;i<ret;i++) { |
97 Event *event = events[i].data.ptr; |
101 Event *event = events[i].data.ptr; |
98 if(!event) { |
102 if(!event) { |
99 ssize_t r = read(ev->eventfd, &event, sizeof(Event*)); |
103 char ebuf[sizeof(Event*)]; |
100 if(r == sizeof(Event*)) { |
104 int ebufpos = 0; |
|
105 char *b = ebuf; |
|
106 while(ebufpos < sizeof(Event*)) { |
|
107 ssize_t r = read(ev->eventin, b + ebufpos, sizeof(Event*)-ebufpos); |
|
108 if(r < 0) { |
|
109 break; |
|
110 } |
|
111 ebufpos += r; |
|
112 } |
|
113 if(ebufpos == sizeof(Event*)) { |
|
114 intptr_t *p = (intptr_t*)b; |
|
115 *(&event) = (Event*)*p; |
101 if(event->fn) { |
116 if(event->fn) { |
102 if(!event->fn(ev, event) && event->finish) { |
117 if(!event->fn(ev, event) && event->finish) { |
103 event->finish(ev, event); |
118 event->finish(ev, event); |
104 } |
119 } |
105 } |
120 } |
106 } |
121 } |
107 } else if(event->fn) { |
122 } else if(event->fn) { |
108 int saved_ev = event->events; |
123 int saved_ev = event->events; |
109 if(!event->fn(ev, event)) { |
124 if(!event->fn(ev, event)) { |
110 // event fn returned 0 -> remove event from epoll |
125 // event fn returned 0 -> remove event from epoll |
111 if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { |
126 if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { |
178 } |
193 } |
179 |
194 |
180 int event_send(EventHandler *h, Event *event) { |
195 int event_send(EventHandler *h, Event *event) { |
181 event->object = 0; |
196 event->object = 0; |
182 event->events = 0; |
197 event->events = 0; |
183 ssize_t r = write(h->eventfd, &event, sizeof(Event*)); |
198 ssize_t r = write(h->eventout, &event, sizeof(Event*)); |
|
199 if(r < sizeof(Event*)) { |
|
200 log_ereport(LOG_FAILURE, "failed to send event: %s", strerror(errno)); |
|
201 } |
184 return r > 0 ? 0 : 1; |
202 return r > 0 ? 0 : 1; |
185 } |
203 } |
186 |
204 |
187 // TODO: remove this fake aio |
205 // TODO: remove this fake aio |
188 int ev_aioread(int fd, aiocb_s *cb) { |
206 int ev_aioread(int fd, aiocb_s *cb) { |