… | |
… | |
58 | |
58 | |
59 | #ifndef EV_USE_EPOLL |
59 | #ifndef EV_USE_EPOLL |
60 | # define EV_USE_EPOLL 0 |
60 | # define EV_USE_EPOLL 0 |
61 | #endif |
61 | #endif |
62 | |
62 | |
|
|
63 | #ifndef CLOCK_REALTIME |
|
|
64 | # define EV_USE_REALTIME 0 |
|
|
65 | #endif |
63 | #ifndef EV_USE_REALTIME |
66 | #ifndef EV_USE_REALTIME |
64 | # define EV_USE_REALTIME 1 /* posix requirement, but might be slower */ |
67 | # define EV_USE_REALTIME 1 /* posix requirement, but might be slower */ |
65 | #endif |
68 | #endif |
66 | |
69 | |
67 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
70 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
68 | #define MAX_BLOCKTIME 59.731 |
71 | #define MAX_BLOCKTIME 59.731 /* never wait longer than this time (to detetc time jumps) */ |
69 | #define PID_HASHSIZE 16 /* size of pid hahs table, must be power of two */ |
72 | #define PID_HASHSIZE 16 /* size of pid hash table, must be power of two */ |
|
|
73 | #define CLEANUP_INTERVAL (MAX_BLOCKTIME * 5.) /* how often to try to free memory and re-check fds */ |
70 | |
74 | |
71 | #include "ev.h" |
75 | #include "ev.h" |
72 | |
76 | |
73 | typedef struct ev_watcher *W; |
77 | typedef struct ev_watcher *W; |
74 | typedef struct ev_watcher_list *WL; |
78 | typedef struct ev_watcher_list *WL; |
… | |
… | |
113 | #endif |
117 | #endif |
114 | |
118 | |
115 | return ev_time (); |
119 | return ev_time (); |
116 | } |
120 | } |
117 | |
121 | |
118 | #define array_nextsize(n) (((n) << 1) | 4 & ~3) |
122 | #define array_roundsize(base,n) ((n) | 4 & ~3) |
119 | #define array_prevsize(n) (((n) >> 1) | 4 & ~3) |
|
|
120 | |
123 | |
121 | #define array_needsize(base,cur,cnt,init) \ |
124 | #define array_needsize(base,cur,cnt,init) \ |
122 | if ((cnt) > cur) \ |
125 | if ((cnt) > cur) \ |
123 | { \ |
126 | { \ |
124 | int newcnt = cur; \ |
127 | int newcnt = cur; \ |
125 | do \ |
128 | do \ |
126 | { \ |
129 | { \ |
127 | newcnt = array_nextsize (newcnt); \ |
130 | newcnt = array_roundsize (base, newcnt << 1); \ |
128 | } \ |
131 | } \ |
129 | while ((cnt) > newcnt); \ |
132 | while ((cnt) > newcnt); \ |
130 | \ |
133 | \ |
131 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
134 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
132 | init (base + cur, newcnt - cur); \ |
135 | init (base + cur, newcnt - cur); \ |
… | |
… | |
165 | static int pendingmax, pendingcnt; |
168 | static int pendingmax, pendingcnt; |
166 | |
169 | |
167 | static void |
170 | static void |
168 | event (W w, int events) |
171 | event (W w, int events) |
169 | { |
172 | { |
170 | if (w->active) |
173 | if (w->pending) |
|
|
174 | { |
|
|
175 | pendings [w->pending - 1].events |= events; |
|
|
176 | return; |
171 | { |
177 | } |
|
|
178 | |
172 | w->pending = ++pendingcnt; |
179 | w->pending = ++pendingcnt; |
173 | array_needsize (pendings, pendingmax, pendingcnt, ); |
180 | array_needsize (pendings, pendingmax, pendingcnt, ); |
174 | pendings [pendingcnt - 1].w = w; |
181 | pendings [pendingcnt - 1].w = w; |
175 | pendings [pendingcnt - 1].events = events; |
182 | pendings [pendingcnt - 1].events = events; |
176 | } |
|
|
177 | } |
183 | } |
178 | |
184 | |
179 | static void |
185 | static void |
180 | queue_events (W *events, int eventcnt, int type) |
186 | queue_events (W *events, int eventcnt, int type) |
181 | { |
187 | { |
… | |
… | |
255 | for (fd = 0; fd < anfdmax; ++fd) |
261 | for (fd = 0; fd < anfdmax; ++fd) |
256 | if (anfds [fd].events) |
262 | if (anfds [fd].events) |
257 | if (fcntl (fd, F_GETFD) == -1 && errno == EBADF) |
263 | if (fcntl (fd, F_GETFD) == -1 && errno == EBADF) |
258 | while (anfds [fd].head) |
264 | while (anfds [fd].head) |
259 | { |
265 | { |
|
|
266 | ev_io_stop (anfds [fd].head); |
260 | event ((W)anfds [fd].head, EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT); |
267 | event ((W)anfds [fd].head, EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT); |
261 | ev_io_stop (anfds [fd].head); |
|
|
262 | } |
268 | } |
263 | } |
269 | } |
264 | |
270 | |
265 | /*****************************************************************************/ |
271 | /*****************************************************************************/ |
266 | |
272 | |
… | |
… | |
529 | { |
535 | { |
530 | while (timercnt && timers [0]->at <= now) |
536 | while (timercnt && timers [0]->at <= now) |
531 | { |
537 | { |
532 | struct ev_timer *w = timers [0]; |
538 | struct ev_timer *w = timers [0]; |
533 | |
539 | |
534 | event ((W)w, EV_TIMEOUT); |
|
|
535 | |
|
|
536 | /* first reschedule or stop timer */ |
540 | /* first reschedule or stop timer */ |
537 | if (w->repeat) |
541 | if (w->repeat) |
538 | { |
542 | { |
539 | w->at = now + w->repeat; |
543 | w->at = now + w->repeat; |
540 | assert (("timer timeout in the past, negative repeat?", w->at > now)); |
544 | assert (("timer timeout in the past, negative repeat?", w->at > now)); |
541 | downheap ((WT *)timers, timercnt, 0); |
545 | downheap ((WT *)timers, timercnt, 0); |
542 | } |
546 | } |
543 | else |
547 | else |
544 | ev_timer_stop (w); /* nonrepeating: stop timer */ |
548 | ev_timer_stop (w); /* nonrepeating: stop timer */ |
|
|
549 | |
|
|
550 | event ((W)w, EV_TIMEOUT); |
545 | } |
551 | } |
546 | } |
552 | } |
547 | |
553 | |
548 | static void |
554 | static void |
549 | periodics_reify (void) |
555 | periodics_reify (void) |