src/server/daemon/event_bsd.c

changeset 385
a1f4cb076d2f
parent 342
ebd1e67c3d5f
child 433
39fe86ae4db0
equal deleted inserted replaced
210:21274e5950af 385:a1f4cb076d2f
65 struct timespec timeout; 65 struct timespec timeout;
66 timeout.tv_nsec = 0; 66 timeout.tv_nsec = 0;
67 timeout.tv_sec = 600; 67 timeout.tv_sec = 600;
68 68
69 struct kevent events[64]; 69 struct kevent events[64];
70 struct kevent changes[64]; 70 struct kevent changes[128];
71 int numchanges = 0; 71 int numchanges = 0;
72 72
73 for(;;) { 73 for(;;) {
74 // wait for events 74 // wait for events
75 int nev = kevent(ev->kqueue, changes, numchanges, events, 64, &timeout); 75 int nev = kevent(ev->kqueue, changes, numchanges, events, 64, &timeout);
76 if(nev == -1) { 76 if(nev == -1) {
77 // TODO: check for error 77 log_ereport(LOG_FAILURE, "kevent: %s", strerror(errno));
78 perror("kevent");
79 continue; 78 continue;
80 } 79 }
81 80
82 numchanges = 0; 81 numchanges = 0;
83 for(int i=0;i<nev;i++) { 82 for(int i=0;i<nev;i++) {
84 Event *event = (Event*)events[i].udata; 83 Event *event = (Event*)events[i].udata;
84 if(!event) {
85 if(events[i].flags == 0) {
86 log_ereport(LOG_WARN, "Unknown kevent (ident=%d)", (int)events[i].ident);
87 }
88 // don't warn in case flags is not 0, because socket EOF events
89 // are triggered even if we apply EV_DELETE in the changelist
90 // the only way to stop this is to apply the changelist without
91 // getting new events, but that comes with a performance penalty
92
93 continue;
94 }
95 int event_events = event->events;
96
85 if(event->fn) { 97 if(event->fn) {
86 int ep = event->events; 98 int saved_ev = event->events;
87 if(event->fn(ev, event)) { 99 if(!event->fn(ev, event)) {
88 if(event->events != ep) { 100 // ret 0 => remove event
89 changes[numchanges++].filter = ev_convert2sys_events(ep); 101
102 if(event->finish) {
103 event->finish(ev, event);
90 } 104 }
91 } else if(event->finish) { 105
92 changes[numchanges++].filter = ev_convert2sys_events(ep); 106 event_events = 0;
93 event->finish(ev, event); 107 } else {
108 event_events = event->events;
109 }
110
111 // if events have changed, we need to add/remove filters
112 if(saved_ev != event_events) {
113 int e = event_events;
114 int e_fd = events[i].ident;
115 if((e & EVENT_POLLIN) != (saved_ev & EVENT_POLLIN)) {
116 if((e & EVENT_POLLIN) == EVENT_POLLIN) {
117 // add
118 EV_SET(&changes[numchanges++], e_fd, EVFILT_READ, EV_ADD, 0, 0, event);
119 } else {
120 // delete
121 EV_SET(&changes[numchanges++], e_fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
122 }
123 }
124 if((e & EVENT_POLLOUT) != (saved_ev & EVENT_POLLOUT)) {
125 if((e & EVENT_POLLOUT) == EVENT_POLLOUT) {
126 // add
127 EV_SET(&changes[numchanges++], e_fd, EVFILT_WRITE, EV_ADD, 0, 0, event);
128 } else {
129 // delete
130 EV_SET(&changes[numchanges++], e_fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
131 }
132 }
94 } 133 }
95 } 134 }
96 } 135 }
97 } 136 }
98 }
99
100 int ev_convert2sys_events(int events) {
101 int e = 0;
102 if((events & EVENT_POLLIN) == EVENT_POLLIN) {
103 e |= EVFILT_READ;
104 }
105 if((events & EVENT_POLLOUT) == EVENT_POLLOUT) {
106 e |= EVFILT_WRITE;
107 }
108 return e;
109 } 137 }
110 138
111 int ev_pollin(EventHandler *h, int fd, Event *event) { 139 int ev_pollin(EventHandler *h, int fd, Event *event) {
112 event->events = EVENT_POLLIN; 140 event->events = EVENT_POLLIN;
113 struct kevent kev; 141 struct kevent kev;
120 struct kevent kev; 148 struct kevent kev;
121 EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, event); 149 EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, event);
122 return kevent(h->kqueue, &kev, 1, NULL, 0, NULL); 150 return kevent(h->kqueue, &kev, 1, NULL, 0, NULL);
123 } 151 }
124 152
153 int ev_remove_poll(EventHandler *h, int fd) {
154 struct kevent kev;
155 EV_SET(&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
156 int r1 = kevent(h->kqueue, &kev, 1, NULL, 0, NULL);
157 EV_SET(&kev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
158 int r2 = kevent(h->kqueue, &kev, 1, NULL, 0, NULL);
159 // in caase r1 or r2 was successful, we return 0 (no error)
160 return r1 != -1 || r2 != -1 ? 0 : 1;
161 }
162
125 int event_send(EventHandler *h, Event *event) { 163 int event_send(EventHandler *h, Event *event) {
126 return 0; 164 return 0;
127 } 165 }
166
167 // TODO: remove this fake aio
168 int ev_aioread(int fd, aiocb_s *cb) {
169 ssize_t result = pread(fd, cb->buf, cb->nbytes, cb->offset);
170 cb->result = result;
171 if(result < 0) {
172 cb->result_errno = errno;
173 }
174 return event_send(cb->evhandler, cb->event);
175 }
176
177 int ev_aiowrite(int fd, aiocb_s *cb) {
178 ssize_t result = pwrite(fd, cb->buf, cb->nbytes, cb->offset);
179 cb->result = result;
180 if(result < 0) {
181 cb->result_errno = errno;
182 }
183 return event_send(cb->evhandler, cb->event);
184 }

mercurial