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 // TODO: check for error |
78 perror("kevent"); |
78 log_ereport(LOG_FAILURE, "kevent: %s", strerror(errno)); |
79 continue; |
79 continue; |
80 } |
80 } |
81 |
81 |
82 numchanges = 0; |
82 numchanges = 0; |
83 for(int i=0;i<nev;i++) { |
83 for(int i=0;i<nev;i++) { |
86 log_ereport(LOG_WARN, "Unknown kevent (ident=%d)", (int)events[i].ident); |
86 log_ereport(LOG_WARN, "Unknown kevent (ident=%d)", (int)events[i].ident); |
87 continue; |
87 continue; |
88 } |
88 } |
89 |
89 |
90 if(event->fn) { |
90 if(event->fn) { |
91 u_short kev_flag = 0; |
|
92 int saved_ev = event->events; |
91 int saved_ev = event->events; |
93 if(!event->fn(ev, event)) { |
92 if(!event->fn(ev, event)) { |
94 // ret 0 => remove event |
93 // ret 0 => remove event |
95 kev_flag = EV_DELETE; |
94 |
96 if(event->finish) { |
95 if(event->finish) { |
97 event->finish(ev, event); |
96 event->finish(ev, event); |
98 } |
97 } |
99 } else if(saved_ev != event->events) { |
98 |
100 // events changed |
99 event->events = 0; |
101 kev_flag = EV_ADD; |
|
102 events[i].filter = ev_convert2sys_events(event->events); |
|
103 } |
100 } |
104 |
101 |
105 if(kev_flag) { |
102 // if events have changed, we need to add/remove filters |
106 // copy current event to changelist |
103 if(saved_ev != event->events) { |
107 changes[numchanges] = events[i]; |
104 int e = event->events; |
108 changes[numchanges].flags = kev_flag; |
105 int e_fd = events[i].ident; |
109 numchanges++; |
106 if((e & EVENT_POLLIN) != (saved_ev & EVENT_POLLIN)) { |
|
107 int f = (e & EVENT_POLLIN) == EVENT_POLLIN ? EV_ADD : EV_DELETE; |
|
108 EV_SET(&changes[numchanges++], e_fd, EVFILT_READ, f, 0, 0, event); |
|
109 } |
|
110 if((e & EVENT_POLLOUT) != (saved_ev & EVENT_POLLOUT)) { |
|
111 int f = (e & EVENT_POLLOUT) == EVENT_POLLOUT ? EV_ADD : EV_DELETE; |
|
112 EV_SET(&changes[numchanges++], e_fd, EVFILT_WRITE, f, 0, 0, event); |
|
113 } |
110 } |
114 } |
111 } |
115 } |
112 } |
116 } |
113 } |
117 } |
114 } |
118 } |