ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.22 by root, Wed Oct 31 19:07:43 2007 UTC vs.
Revision 1.27 by root, Wed Oct 31 22:16:36 2007 UTC

113} 113}
114 114
115#define array_needsize(base,cur,cnt,init) \ 115#define array_needsize(base,cur,cnt,init) \
116 if ((cnt) > cur) \ 116 if ((cnt) > cur) \
117 { \ 117 { \
118 int newcnt = cur ? cur << 1 : 16; \ 118 int newcnt = cur; \
119 do \
120 { \
121 newcnt = (newcnt << 1) | 4 & ~3; \
122 } \
123 while ((cnt) > newcnt); \
124 \
119 base = realloc (base, sizeof (*base) * (newcnt)); \ 125 base = realloc (base, sizeof (*base) * (newcnt)); \
120 init (base + cur, newcnt - cur); \ 126 init (base + cur, newcnt - cur); \
121 cur = newcnt; \ 127 cur = newcnt; \
122 } 128 }
123 129
124/*****************************************************************************/ 130/*****************************************************************************/
125 131
126typedef struct 132typedef struct
127{ 133{
128 struct ev_io *head; 134 struct ev_io *head;
129 unsigned char wev, rev; /* want, received event set */ 135 int events;
130} ANFD; 136} ANFD;
131 137
132static ANFD *anfds; 138static ANFD *anfds;
133static int anfdmax; 139static int anfdmax;
134 140
135static int *fdchanges;
136static int fdchangemax, fdchangecnt;
137
138static void 141static void
139anfds_init (ANFD *base, int count) 142anfds_init (ANFD *base, int count)
140{ 143{
141 while (count--) 144 while (count--)
142 { 145 {
143 base->head = 0; 146 base->head = 0;
144 base->wev = base->rev = EV_NONE; 147 base->events = EV_NONE;
145 ++base; 148 ++base;
146 } 149 }
147} 150}
148 151
149typedef struct 152typedef struct
166 pendings [pendingcnt - 1].events = events; 169 pendings [pendingcnt - 1].events = events;
167 } 170 }
168} 171}
169 172
170static void 173static void
174queue_events (W *events, int eventcnt, int type)
175{
176 int i;
177
178 for (i = 0; i < eventcnt; ++i)
179 event (events [i], type);
180}
181
182static void
171fd_event (int fd, int events) 183fd_event (int fd, int events)
172{ 184{
173 ANFD *anfd = anfds + fd; 185 ANFD *anfd = anfds + fd;
174 struct ev_io *w; 186 struct ev_io *w;
175 187
180 if (ev) 192 if (ev)
181 event ((W)w, ev); 193 event ((W)w, ev);
182 } 194 }
183} 195}
184 196
197/*****************************************************************************/
198
199static int *fdchanges;
200static int fdchangemax, fdchangecnt;
201
185static void 202static void
186queue_events (W *events, int eventcnt, int type) 203fd_reify (void)
187{ 204{
188 int i; 205 int i;
189 206
190 for (i = 0; i < eventcnt; ++i) 207 for (i = 0; i < fdchangecnt; ++i)
191 event (events [i], type); 208 {
209 int fd = fdchanges [i];
210 ANFD *anfd = anfds + fd;
211 struct ev_io *w;
212
213 int events = 0;
214
215 for (w = anfd->head; w; w = w->next)
216 events |= w->events;
217
218 anfd->events &= ~EV_REIFY;
219
220 if (anfd->events != events)
221 {
222 method_modify (fd, anfd->events, events);
223 anfd->events = events;
224 }
225 }
226
227 fdchangecnt = 0;
228}
229
230static void
231fd_change (int fd)
232{
233 if (anfds [fd].events & EV_REIFY)
234 return;
235
236 anfds [fd].events |= EV_REIFY;
237
238 ++fdchangecnt;
239 array_needsize (fdchanges, fdchangemax, fdchangecnt, );
240 fdchanges [fdchangecnt - 1] = fd;
192} 241}
193 242
194/* called on EBADF to verify fds */ 243/* called on EBADF to verify fds */
195static void 244static void
196fd_recheck () 245fd_recheck (void)
197{ 246{
198 int fd; 247 int fd;
199 248
200 for (fd = 0; fd < anfdmax; ++fd) 249 for (fd = 0; fd < anfdmax; ++fd)
201 if (anfds [fd].wev) 250 if (anfds [fd].events)
202 if (fcntl (fd, F_GETFD) == -1 && errno == EBADF) 251 if (fcntl (fd, F_GETFD) == -1 && errno == EBADF)
203 while (anfds [fd].head) 252 while (anfds [fd].head)
253 {
254 event ((W)anfds [fd].head, EV_ERROR);
204 evio_stop (anfds [fd].head); 255 evio_stop (anfds [fd].head);
256 }
205} 257}
206 258
207/*****************************************************************************/ 259/*****************************************************************************/
208 260
209static struct ev_timer **timers; 261static struct ev_timer **timers;
366#endif 418#endif
367#if HAVE_SELECT 419#if HAVE_SELECT
368# include "ev_select.c" 420# include "ev_select.c"
369#endif 421#endif
370 422
423int
424ev_version_major (void)
425{
426 return EV_VERSION_MAJOR;
427}
428
429int
430ev_version_minor (void)
431{
432 return EV_VERSION_MINOR;
433}
434
371int ev_init (int flags) 435int ev_init (int flags)
372{ 436{
437 if (!ev_method)
438 {
373#if HAVE_MONOTONIC 439#if HAVE_MONOTONIC
374 { 440 {
375 struct timespec ts; 441 struct timespec ts;
376 if (!clock_gettime (CLOCK_MONOTONIC, &ts)) 442 if (!clock_gettime (CLOCK_MONOTONIC, &ts))
377 have_monotonic = 1; 443 have_monotonic = 1;
378 } 444 }
379#endif 445#endif
380 446
381 ev_now = ev_time (); 447 ev_now = ev_time ();
382 now = get_clock (); 448 now = get_clock ();
383 diff = ev_now - now; 449 diff = ev_now - now;
384 450
385 if (pipe (sigpipe)) 451 if (pipe (sigpipe))
386 return 0; 452 return 0;
387 453
388 ev_method = EVMETHOD_NONE; 454 ev_method = EVMETHOD_NONE;
389#if HAVE_EPOLL 455#if HAVE_EPOLL
390 if (ev_method == EVMETHOD_NONE) epoll_init (flags); 456 if (ev_method == EVMETHOD_NONE) epoll_init (flags);
391#endif 457#endif
392#if HAVE_SELECT 458#if HAVE_SELECT
393 if (ev_method == EVMETHOD_NONE) select_init (flags); 459 if (ev_method == EVMETHOD_NONE) select_init (flags);
394#endif 460#endif
395 461
396 if (ev_method) 462 if (ev_method)
397 { 463 {
398 evw_init (&sigev, sigcb); 464 evw_init (&sigev, sigcb);
399 siginit (); 465 siginit ();
400 466
401 evsignal_init (&childev, childcb, SIGCHLD); 467 evsignal_init (&childev, childcb, SIGCHLD);
402 evsignal_start (&childev); 468 evsignal_start (&childev);
469 }
403 } 470 }
404 471
405 return ev_method; 472 return ev_method;
406} 473}
407 474
408/*****************************************************************************/ 475/*****************************************************************************/
409 476
477void
410void ev_prefork (void) 478ev_prefork (void)
411{ 479{
412 /* nop */ 480 /* nop */
413} 481}
414 482
483void
415void ev_postfork_parent (void) 484ev_postfork_parent (void)
416{ 485{
417 /* nop */ 486 /* nop */
418} 487}
419 488
489void
420void ev_postfork_child (void) 490ev_postfork_child (void)
421{ 491{
422#if HAVE_EPOLL 492#if HAVE_EPOLL
423 if (ev_method == EVMETHOD_EPOLL) 493 if (ev_method == EVMETHOD_EPOLL)
424 epoll_postfork_child (); 494 epoll_postfork_child ();
425#endif 495#endif
432} 502}
433 503
434/*****************************************************************************/ 504/*****************************************************************************/
435 505
436static void 506static void
437fd_reify (void)
438{
439 int i;
440
441 for (i = 0; i < fdchangecnt; ++i)
442 {
443 int fd = fdchanges [i];
444 ANFD *anfd = anfds + fd;
445 struct ev_io *w;
446
447 int wev = 0;
448
449 for (w = anfd->head; w; w = w->next)
450 wev |= w->events;
451
452 if (anfd->wev != wev)
453 {
454 method_modify (fd, anfd->wev, wev);
455 anfd->wev = wev;
456 }
457 }
458
459 fdchangecnt = 0;
460}
461
462static void
463call_pending () 507call_pending (void)
464{ 508{
465 while (pendingcnt) 509 while (pendingcnt)
466 { 510 {
467 ANPENDING *p = pendings + --pendingcnt; 511 ANPENDING *p = pendings + --pendingcnt;
468 512
473 } 517 }
474 } 518 }
475} 519}
476 520
477static void 521static void
478timers_reify () 522timers_reify (void)
479{ 523{
480 while (timercnt && timers [0]->at <= now) 524 while (timercnt && timers [0]->at <= now)
481 { 525 {
482 struct ev_timer *w = timers [0]; 526 struct ev_timer *w = timers [0];
483 527
494 evtimer_stop (w); /* nonrepeating: stop timer */ 538 evtimer_stop (w); /* nonrepeating: stop timer */
495 } 539 }
496} 540}
497 541
498static void 542static void
499periodics_reify () 543periodics_reify (void)
500{ 544{
501 while (periodiccnt && periodics [0]->at <= ev_now) 545 while (periodiccnt && periodics [0]->at <= ev_now)
502 { 546 {
503 struct ev_periodic *w = periodics [0]; 547 struct ev_periodic *w = periodics [0];
504 548
540 } 584 }
541 } 585 }
542} 586}
543 587
544static void 588static void
545time_update () 589time_update (void)
546{ 590{
547 int i; 591 int i;
548 592
549 ev_now = ev_time (); 593 ev_now = ev_time ();
550 594
584int ev_loop_done; 628int ev_loop_done;
585 629
586void ev_loop (int flags) 630void ev_loop (int flags)
587{ 631{
588 double block; 632 double block;
589 ev_loop_done = flags & EVLOOP_ONESHOT ? 1 : 0; 633 ev_loop_done = flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK) ? 1 : 0;
590 634
591 do 635 do
592 { 636 {
593 /* queue check watchers (and execute them) */ 637 /* queue check watchers (and execute them) */
594 if (preparecnt) 638 if (preparecnt)
710 754
711 ev_start ((W)w, 1); 755 ev_start ((W)w, 1);
712 array_needsize (anfds, anfdmax, fd + 1, anfds_init); 756 array_needsize (anfds, anfdmax, fd + 1, anfds_init);
713 wlist_add ((WL *)&anfds[fd].head, (WL)w); 757 wlist_add ((WL *)&anfds[fd].head, (WL)w);
714 758
715 ++fdchangecnt; 759 fd_change (fd);
716 array_needsize (fdchanges, fdchangemax, fdchangecnt, );
717 fdchanges [fdchangecnt - 1] = fd;
718} 760}
719 761
720void 762void
721evio_stop (struct ev_io *w) 763evio_stop (struct ev_io *w)
722{ 764{
725 return; 767 return;
726 768
727 wlist_del ((WL *)&anfds[w->fd].head, (WL)w); 769 wlist_del ((WL *)&anfds[w->fd].head, (WL)w);
728 ev_stop ((W)w); 770 ev_stop ((W)w);
729 771
730 ++fdchangecnt; 772 fd_change (w->fd);
731 array_needsize (fdchanges, fdchangemax, fdchangecnt, );
732 fdchanges [fdchangecnt - 1] = w->fd;
733} 773}
734 774
735void 775void
736evtimer_start (struct ev_timer *w) 776evtimer_start (struct ev_timer *w)
737{ 777{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines