src/server/daemon/event_linux.c

changeset 133
87b405d61f64
parent 126
631aaa01b2b5
child 152
8b85c5face66
equal deleted inserted replaced
132:e9afb5387007 133:87b405d61f64
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 }

mercurial