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

Comparing libev/ev.c (file contents):
Revision 1.40 by root, Fri Nov 2 11:02:23 2007 UTC vs.
Revision 1.43 by root, Fri Nov 2 20:21:33 2007 UTC

56 56
57#ifndef EV_USE_SELECT 57#ifndef EV_USE_SELECT
58# define EV_USE_SELECT 1 58# define EV_USE_SELECT 1
59#endif 59#endif
60 60
61#ifndef EV_USE_POLL
62# define EV_USE_POLL 0 /* poll is usually slower than select, and not as well tested */
63#endif
64
61#ifndef EV_USE_EPOLL 65#ifndef EV_USE_EPOLL
62# define EV_USE_EPOLL 0 66# define EV_USE_EPOLL 0
63#endif 67#endif
64 68
65#ifndef EV_USE_REALTIME 69#ifndef EV_USE_REALTIME
95# define inline static 99# define inline static
96#endif 100#endif
97 101
98#define expect_false(expr) expect ((expr) != 0, 0) 102#define expect_false(expr) expect ((expr) != 0, 0)
99#define expect_true(expr) expect ((expr) != 0, 1) 103#define expect_true(expr) expect ((expr) != 0, 1)
104
105#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
106#define ABSPRI(w) ((w)->priority - EV_MINPRI)
100 107
101typedef struct ev_watcher *W; 108typedef struct ev_watcher *W;
102typedef struct ev_watcher_list *WL; 109typedef struct ev_watcher_list *WL;
103typedef struct ev_watcher_time *WT; 110typedef struct ev_watcher_time *WT;
104 111
189{ 196{
190 W w; 197 W w;
191 int events; 198 int events;
192} ANPENDING; 199} ANPENDING;
193 200
194static ANPENDING *pendings; 201static ANPENDING *pendings [NUMPRI];
195static int pendingmax, pendingcnt; 202static int pendingmax [NUMPRI], pendingcnt [NUMPRI];
196 203
197static void 204static void
198event (W w, int events) 205event (W w, int events)
199{ 206{
200 if (w->pending) 207 if (w->pending)
201 { 208 {
202 pendings [w->pending - 1].events |= events; 209 pendings [ABSPRI (w)][w->pending - 1].events |= events;
203 return; 210 return;
204 } 211 }
205 212
206 w->pending = ++pendingcnt; 213 w->pending = ++pendingcnt [ABSPRI (w)];
207 array_needsize (pendings, pendingmax, pendingcnt, ); 214 array_needsize (pendings [ABSPRI (w)], pendingmax [ABSPRI (w)], pendingcnt [ABSPRI (w)], );
208 pendings [pendingcnt - 1].w = w; 215 pendings [ABSPRI (w)][w->pending - 1].w = w;
209 pendings [pendingcnt - 1].events = events; 216 pendings [ABSPRI (w)][w->pending - 1].events = events;
210} 217}
211 218
212static void 219static void
213queue_events (W *events, int eventcnt, int type) 220queue_events (W *events, int eventcnt, int type)
214{ 221{
277 ++fdchangecnt; 284 ++fdchangecnt;
278 array_needsize (fdchanges, fdchangemax, fdchangecnt, ); 285 array_needsize (fdchanges, fdchangemax, fdchangecnt, );
279 fdchanges [fdchangecnt - 1] = fd; 286 fdchanges [fdchangecnt - 1] = fd;
280} 287}
281 288
289static void
290fd_kill (int fd)
291{
292 struct ev_io *w;
293
294 printf ("killing fd %d\n", fd);//D
295 while ((w = anfds [fd].head))
296 {
297 ev_io_stop (w);
298 event ((W)w, EV_ERROR | EV_READ | EV_WRITE);
299 }
300}
301
282/* called on EBADF to verify fds */ 302/* called on EBADF to verify fds */
283static void 303static void
284fd_recheck (void) 304fd_ebadf (void)
285{ 305{
286 int fd; 306 int fd;
287 307
288 for (fd = 0; fd < anfdmax; ++fd) 308 for (fd = 0; fd < anfdmax; ++fd)
289 if (anfds [fd].events) 309 if (anfds [fd].events)
290 if (fcntl (fd, F_GETFD) == -1 && errno == EBADF) 310 if (fcntl (fd, F_GETFD) == -1 && errno == EBADF)
291 while (anfds [fd].head) 311 fd_kill (fd);
312}
313
314/* called on ENOMEM in select/poll to kill some fds and retry */
315static void
316fd_enomem (void)
317{
318 int fd = anfdmax;
319
320 while (fd--)
321 if (anfds [fd].events)
292 { 322 {
293 ev_io_stop (anfds [fd].head); 323 close (fd);
294 event ((W)anfds [fd].head, EV_ERROR | EV_READ | EV_WRITE); 324 fd_kill (fd);
325 return;
295 } 326 }
296} 327}
297 328
298/*****************************************************************************/ 329/*****************************************************************************/
299 330
300static struct ev_timer **timers; 331static struct ev_timer **timers;
454/*****************************************************************************/ 485/*****************************************************************************/
455 486
456#if EV_USE_EPOLL 487#if EV_USE_EPOLL
457# include "ev_epoll.c" 488# include "ev_epoll.c"
458#endif 489#endif
490#if EV_USE_POLL
491# include "ev_poll.c"
492#endif
459#if EV_USE_SELECT 493#if EV_USE_SELECT
460# include "ev_select.c" 494# include "ev_select.c"
461#endif 495#endif
462 496
463int 497int
470ev_version_minor (void) 504ev_version_minor (void)
471{ 505{
472 return EV_VERSION_MINOR; 506 return EV_VERSION_MINOR;
473} 507}
474 508
509/* return true if we are running with elevated privileges and ignore env variables */
510static int
511enable_secure ()
512{
513 return getuid () != geteuid ()
514 || getgid () != getegid ();
515}
516
475int ev_init (int flags) 517int ev_init (int methods)
476{ 518{
477 if (!ev_method) 519 if (!ev_method)
478 { 520 {
479#if EV_USE_MONOTONIC 521#if EV_USE_MONOTONIC
480 { 522 {
490 diff = ev_now - now; 532 diff = ev_now - now;
491 533
492 if (pipe (sigpipe)) 534 if (pipe (sigpipe))
493 return 0; 535 return 0;
494 536
537 if (methods == EVMETHOD_AUTO)
538 if (!enable_secure () && getenv ("LIBEV_METHODS"))
539 methods = atoi (getenv ("LIBEV_METHODS"));
540 else
495 ev_method = EVMETHOD_NONE; 541 methods = EVMETHOD_ANY;
542
543 ev_method = 0;
496#if EV_USE_EPOLL 544#if EV_USE_EPOLL
497 if (ev_method == EVMETHOD_NONE) epoll_init (flags); 545 if (!ev_method && (methods & EVMETHOD_EPOLL )) epoll_init (methods);
546#endif
547#if EV_USE_POLL
548 if (!ev_method && (methods & EVMETHOD_POLL )) poll_init (methods);
498#endif 549#endif
499#if EV_USE_SELECT 550#if EV_USE_SELECT
500 if (ev_method == EVMETHOD_NONE) select_init (flags); 551 if (!ev_method && (methods & EVMETHOD_SELECT)) select_init (methods);
501#endif 552#endif
502 553
503 if (ev_method) 554 if (ev_method)
504 { 555 {
505 ev_watcher_init (&sigev, sigcb); 556 ev_watcher_init (&sigev, sigcb);
545/*****************************************************************************/ 596/*****************************************************************************/
546 597
547static void 598static void
548call_pending (void) 599call_pending (void)
549{ 600{
601 int pri;
602
603 for (pri = NUMPRI; pri--; )
550 while (pendingcnt) 604 while (pendingcnt [pri])
551 { 605 {
552 ANPENDING *p = pendings + --pendingcnt; 606 ANPENDING *p = pendings [pri] + --pendingcnt [pri];
553 607
554 if (p->w) 608 if (p->w)
555 { 609 {
556 p->w->pending = 0; 610 p->w->pending = 0;
557 p->w->cb (p->w, p->events); 611 p->w->cb (p->w, p->events);
558 } 612 }
559 } 613 }
560} 614}
561 615
562static void 616static void
563timers_reify (void) 617timers_reify (void)
564{ 618{
796static void 850static void
797ev_clear_pending (W w) 851ev_clear_pending (W w)
798{ 852{
799 if (w->pending) 853 if (w->pending)
800 { 854 {
801 pendings [w->pending - 1].w = 0; 855 pendings [ABSPRI (w)][w->pending - 1].w = 0;
802 w->pending = 0; 856 w->pending = 0;
803 } 857 }
804} 858}
805 859
806static void 860static void
807ev_start (W w, int active) 861ev_start (W w, int active)
808{ 862{
863 if (w->priority < EV_MINPRI) w->priority = EV_MINPRI;
864 if (w->priority > EV_MAXPRI) w->priority = EV_MAXPRI;
865
809 w->active = active; 866 w->active = active;
810} 867}
811 868
812static void 869static void
813ev_stop (W w) 870ev_stop (W w)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines