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

Comparing libev/ev.c (file contents):
Revision 1.4 by root, Tue Oct 30 23:10:33 2007 UTC vs.
Revision 1.7 by root, Wed Oct 31 00:24:16 2007 UTC

1#include <math.h> 1#include <math.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <unistd.h>
4#include <fcntl.h>
5#include <signal.h>
3 6
4#include <stdio.h> 7#include <stdio.h>
5 8
6#include <assert.h> 9#include <assert.h>
7#include <errno.h> 10#include <errno.h>
10 13
11#ifdef CLOCK_MONOTONIC 14#ifdef CLOCK_MONOTONIC
12# define HAVE_MONOTONIC 1 15# define HAVE_MONOTONIC 1
13#endif 16#endif
14 17
18#define HAVE_REALTIME 1
15#define HAVE_EPOLL 1 19#define HAVE_EPOLL 1
16#define HAVE_REALTIME 1
17#define HAVE_SELECT 0 20#define HAVE_SELECT 1
18 21
19#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ 22#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
20#define MAX_BLOCKTIME 60. 23#define MAX_BLOCKTIME 60.
21 24
22#include "ev.h" 25#include "ev.h"
34int ev_method; 37int ev_method;
35 38
36static int have_monotonic; /* runtime */ 39static int have_monotonic; /* runtime */
37 40
38static ev_tstamp method_fudge; /* stupid epoll-returns-early bug */ 41static ev_tstamp method_fudge; /* stupid epoll-returns-early bug */
39static void (*method_reify)(void); 42static void (*method_modify)(int fd, int oev, int nev);
40static void (*method_poll)(ev_tstamp timeout); 43static void (*method_poll)(ev_tstamp timeout);
41 44
42ev_tstamp 45ev_tstamp
43ev_time (void) 46ev_time (void)
44{ 47{
179 182
180 timers [k] = w; 183 timers [k] = w;
181 timers [k]->active = k + 1; 184 timers [k]->active = k + 1;
182} 185}
183 186
184static struct ev_signal **signals; 187typedef struct
188{
189 struct ev_signal *head;
190 sig_atomic_t gotsig;
191} ANSIG;
192
193static ANSIG *signals;
185static int signalmax; 194static int signalmax;
186 195
196static int sigpipe [2];
197static sig_atomic_t gotsig;
198static struct ev_io sigev;
199
187static void 200static void
188signals_init (struct ev_signal **base, int count) 201signals_init (ANSIG *base, int count)
189{ 202{
190 while (count--) 203 while (count--)
191 *base++ = 0; 204 {
205 base->head = 0;
206 base->gotsig = 0;
207 ++base;
208 }
209}
210
211static void
212sighandler (int signum)
213{
214 signals [signum - 1].gotsig = 1;
215
216 if (!gotsig)
217 {
218 gotsig = 1;
219 write (sigpipe [1], &gotsig, 1);
220 }
221}
222
223static void
224sigcb (struct ev_io *iow, int revents)
225{
226 struct ev_signal *w;
227 int sig;
228
229 gotsig = 0;
230 read (sigpipe [0], &revents, 1);
231
232 for (sig = signalmax; sig--; )
233 if (signals [sig].gotsig)
234 {
235 signals [sig].gotsig = 0;
236
237 for (w = signals [sig].head; w; w = w->next)
238 event ((struct ev_watcher *)w, EV_SIGNAL);
239 }
240}
241
242static void
243siginit (void)
244{
245 fcntl (sigpipe [0], F_SETFD, FD_CLOEXEC);
246 fcntl (sigpipe [1], F_SETFD, FD_CLOEXEC);
247
248 /* rather than sort out wether we really need nb, set it */
249 fcntl (sigpipe [0], F_SETFL, O_NONBLOCK);
250 fcntl (sigpipe [1], F_SETFL, O_NONBLOCK);
251
252 evio_set (&sigev, sigpipe [0], EV_READ);
253 evio_start (&sigev);
192} 254}
193 255
194#if HAVE_EPOLL 256#if HAVE_EPOLL
195# include "ev_epoll.c" 257# include "ev_epoll.c"
196#endif 258#endif
210 272
211 ev_now = ev_time (); 273 ev_now = ev_time ();
212 now = get_clock (); 274 now = get_clock ();
213 diff = ev_now - now; 275 diff = ev_now - now;
214 276
277 if (pipe (sigpipe))
278 return 0;
279
280 ev_method = EVMETHOD_NONE;
215#if HAVE_EPOLL 281#if HAVE_EPOLL
216 if (epoll_init (flags)) 282 if (ev_method == EVMETHOD_NONE) epoll_init (flags);
217 return ev_method;
218#endif 283#endif
219#if HAVE_SELECT 284#if HAVE_SELECT
220 if (select_init (flags)) 285 if (ev_method == EVMETHOD_NONE) select_init (flags);
221 return ev_method;
222#endif 286#endif
223 287
224 ev_method = EVMETHOD_NONE; 288 if (ev_method)
289 {
290 evw_init (&sigev, sigcb, 0);
291 siginit ();
292 }
293
225 return ev_method; 294 return ev_method;
226} 295}
227 296
228void ev_prefork (void) 297void ev_prefork (void)
229{ 298{
234} 303}
235 304
236void ev_postfork_child (void) 305void ev_postfork_child (void)
237{ 306{
238#if HAVE_EPOLL 307#if HAVE_EPOLL
308 if (ev_method == EVMETHOD_EPOLL)
239 epoll_postfork_child (); 309 epoll_postfork_child ();
240#endif 310#endif
311
312 evio_stop (&sigev);
313 close (sigpipe [0]);
314 close (sigpipe [1]);
315 pipe (sigpipe);
316 siginit ();
317}
318
319static void
320fd_reify (void)
321{
322 int i;
323
324 for (i = 0; i < fdchangecnt; ++i)
325 {
326 int fd = fdchanges [i];
327 ANFD *anfd = anfds + fd;
328 struct ev_io *w;
329
330 int wev = 0;
331
332 for (w = anfd->head; w; w = w->next)
333 wev |= w->events;
334
335 if (anfd->wev != wev)
336 {
337 method_modify (fd, anfd->wev, wev);
338 anfd->wev = wev;
339 }
340 }
341
342 fdchangecnt = 0;
241} 343}
242 344
243static void 345static void
244call_pending () 346call_pending ()
245{ 347{
336 ev_loop_done = flags & EVLOOP_ONESHOT; 438 ev_loop_done = flags & EVLOOP_ONESHOT;
337 439
338 do 440 do
339 { 441 {
340 /* update fd-related kernel structures */ 442 /* update fd-related kernel structures */
341 method_reify (); fdchangecnt = 0; 443 fd_reify ();
342 444
343 /* calculate blocking time */ 445 /* calculate blocking time */
344 if (flags & EVLOOP_NONBLOCK) 446 if (flags & EVLOOP_NONBLOCK)
345 block = 0.; 447 block = 0.;
346 else 448 else
509 if (ev_is_active (w)) 611 if (ev_is_active (w))
510 return; 612 return;
511 613
512 ev_start ((struct ev_watcher *)w, 1); 614 ev_start ((struct ev_watcher *)w, 1);
513 array_needsize (signals, signalmax, w->signum, signals_init); 615 array_needsize (signals, signalmax, w->signum, signals_init);
514 wlist_add ((struct ev_watcher_list **)&signals [w->signum - 1], (struct ev_watcher_list *)w); 616 wlist_add ((struct ev_watcher_list **)&signals [w->signum - 1].head, (struct ev_watcher_list *)w);
617
618 if (!w->next)
619 {
620 struct sigaction sa;
621 sa.sa_handler = sighandler;
622 sigfillset (&sa.sa_mask);
623 sa.sa_flags = 0;
624 sigaction (w->signum, &sa, 0);
625 }
515} 626}
516 627
517void 628void
518evsignal_stop (struct ev_signal *w) 629evsignal_stop (struct ev_signal *w)
519{ 630{
520 if (!ev_is_active (w)) 631 if (!ev_is_active (w))
521 return; 632 return;
522 633
523 wlist_del ((struct ev_watcher_list **)&signals [w->signum - 1], (struct ev_watcher_list *)w); 634 wlist_del ((struct ev_watcher_list **)&signals [w->signum - 1].head, (struct ev_watcher_list *)w);
524 ev_stop ((struct ev_watcher *)w); 635 ev_stop ((struct ev_watcher *)w);
636
637 if (!signals [w->signum - 1].head)
638 signal (w->signum, SIG_DFL);
525} 639}
526 640
527/*****************************************************************************/ 641/*****************************************************************************/
528#if 1 642#if 1
529 643
539 //fprintf (stderr, "timer %f,%f (%x) (%f) d%p\n", w->at, w->repeat, revents, w->at - ev_time (), w->data); 653 //fprintf (stderr, "timer %f,%f (%x) (%f) d%p\n", w->at, w->repeat, revents, w->at - ev_time (), w->data);
540 evtimer_stop (w); 654 evtimer_stop (w);
541 evtimer_start (w); 655 evtimer_start (w);
542} 656}
543 657
658static void
659scb (struct ev_signal *w, int revents)
660{
661 fprintf (stderr, "signal %x,%d\n", revents, w->signum);
662}
663
544int main (void) 664int main (void)
545{ 665{
546 struct ev_io sin; 666 struct ev_io sin;
547 667
548 ev_init (0); 668 ev_init (0);
551 evio_set (&sin, 0, EV_READ); 671 evio_set (&sin, 0, EV_READ);
552 evio_start (&sin); 672 evio_start (&sin);
553 673
554 struct ev_timer t[10000]; 674 struct ev_timer t[10000];
555 675
556#if 1 676#if 0
557 int i; 677 int i;
558 for (i = 0; i < 10000; ++i) 678 for (i = 0; i < 10000; ++i)
559 { 679 {
560 struct ev_timer *w = t + i; 680 struct ev_timer *w = t + i;
561 evw_init (w, ocb, i); 681 evw_init (w, ocb, i);
569 struct ev_timer t1; 689 struct ev_timer t1;
570 evw_init (&t1, ocb, 0); 690 evw_init (&t1, ocb, 0);
571 evtimer_set_abs (&t1, 5, 10); 691 evtimer_set_abs (&t1, 5, 10);
572 evtimer_start (&t1); 692 evtimer_start (&t1);
573 693
694 struct ev_signal sig;
695 evw_init (&sig, scb, 65535);
696 evsignal_set (&sig, SIGQUIT);
697 evsignal_start (&sig);
698
574 ev_loop (0); 699 ev_loop (0);
575 700
576 return 0; 701 return 0;
577} 702}
578 703

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines