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

Comparing libev/ev.c (file contents):
Revision 1.6 by root, Tue Oct 30 23:55:29 2007 UTC vs.
Revision 1.8 by root, Wed Oct 31 00:32:33 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>
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_modify)(int fd, int oev, int nev); 42static void (*method_modify)(int fd, int oev, int nev);
40static void (*method_poll)(ev_tstamp timeout); 43static void (*method_poll)(ev_tstamp timeout);
44
45/*****************************************************************************/
41 46
42ev_tstamp 47ev_tstamp
43ev_time (void) 48ev_time (void)
44{ 49{
45#if HAVE_REALTIME 50#if HAVE_REALTIME
76 base = realloc (base, sizeof (*base) * (newcnt)); \ 81 base = realloc (base, sizeof (*base) * (newcnt)); \
77 init (base + cur, newcnt - cur); \ 82 init (base + cur, newcnt - cur); \
78 cur = newcnt; \ 83 cur = newcnt; \
79 } 84 }
80 85
86/*****************************************************************************/
87
81typedef struct 88typedef struct
82{ 89{
83 struct ev_io *head; 90 struct ev_io *head;
84 unsigned char wev, rev; /* want, received event set */ 91 unsigned char wev, rev; /* want, received event set */
85} ANFD; 92} ANFD;
132 if (ev) 139 if (ev)
133 event ((struct ev_watcher *)w, ev); 140 event ((struct ev_watcher *)w, ev);
134 } 141 }
135} 142}
136 143
144/*****************************************************************************/
145
137static struct ev_timer **atimers; 146static struct ev_timer **atimers;
138static int atimermax, atimercnt; 147static int atimermax, atimercnt;
139 148
140static struct ev_timer **rtimers; 149static struct ev_timer **rtimers;
141static int rtimermax, rtimercnt; 150static int rtimermax, rtimercnt;
179 188
180 timers [k] = w; 189 timers [k] = w;
181 timers [k]->active = k + 1; 190 timers [k]->active = k + 1;
182} 191}
183 192
184static struct ev_signal **signals; 193/*****************************************************************************/
194
195typedef struct
196{
197 struct ev_signal *head;
198 sig_atomic_t gotsig;
199} ANSIG;
200
201static ANSIG *signals;
185static int signalmax; 202static int signalmax;
186 203
204static int sigpipe [2];
205static sig_atomic_t gotsig;
206static struct ev_io sigev;
207
187static void 208static void
188signals_init (struct ev_signal **base, int count) 209signals_init (ANSIG *base, int count)
189{ 210{
190 while (count--) 211 while (count--)
191 *base++ = 0; 212 {
213 base->head = 0;
214 base->gotsig = 0;
215 ++base;
216 }
192} 217}
218
219static void
220sighandler (int signum)
221{
222 signals [signum - 1].gotsig = 1;
223
224 if (!gotsig)
225 {
226 gotsig = 1;
227 write (sigpipe [1], &gotsig, 1);
228 }
229}
230
231static void
232sigcb (struct ev_io *iow, int revents)
233{
234 struct ev_signal *w;
235 int sig;
236
237 gotsig = 0;
238 read (sigpipe [0], &revents, 1);
239
240 for (sig = signalmax; sig--; )
241 if (signals [sig].gotsig)
242 {
243 signals [sig].gotsig = 0;
244
245 for (w = signals [sig].head; w; w = w->next)
246 event ((struct ev_watcher *)w, EV_SIGNAL);
247 }
248}
249
250static void
251siginit (void)
252{
253 fcntl (sigpipe [0], F_SETFD, FD_CLOEXEC);
254 fcntl (sigpipe [1], F_SETFD, FD_CLOEXEC);
255
256 /* rather than sort out wether we really need nb, set it */
257 fcntl (sigpipe [0], F_SETFL, O_NONBLOCK);
258 fcntl (sigpipe [1], F_SETFL, O_NONBLOCK);
259
260 evio_set (&sigev, sigpipe [0], EV_READ);
261 evio_start (&sigev);
262}
263
264/*****************************************************************************/
193 265
194#if HAVE_EPOLL 266#if HAVE_EPOLL
195# include "ev_epoll.c" 267# include "ev_epoll.c"
196#endif 268#endif
197#if HAVE_SELECT 269#if HAVE_SELECT
210 282
211 ev_now = ev_time (); 283 ev_now = ev_time ();
212 now = get_clock (); 284 now = get_clock ();
213 diff = ev_now - now; 285 diff = ev_now - now;
214 286
287 if (pipe (sigpipe))
288 return 0;
289
290 ev_method = EVMETHOD_NONE;
215#if HAVE_EPOLL 291#if HAVE_EPOLL
216 if (epoll_init (flags)) 292 if (ev_method == EVMETHOD_NONE) epoll_init (flags);
217 return ev_method;
218#endif 293#endif
219#if HAVE_SELECT 294#if HAVE_SELECT
220 if (select_init (flags)) 295 if (ev_method == EVMETHOD_NONE) select_init (flags);
221 return ev_method;
222#endif 296#endif
223 297
224 ev_method = EVMETHOD_NONE; 298 if (ev_method)
299 {
300 evw_init (&sigev, sigcb, 0);
301 siginit ();
302 }
303
225 return ev_method; 304 return ev_method;
226} 305}
306
307/*****************************************************************************/
227 308
228void ev_prefork (void) 309void ev_prefork (void)
229{ 310{
230} 311}
231 312
237{ 318{
238#if HAVE_EPOLL 319#if HAVE_EPOLL
239 if (ev_method == EVMETHOD_EPOLL) 320 if (ev_method == EVMETHOD_EPOLL)
240 epoll_postfork_child (); 321 epoll_postfork_child ();
241#endif 322#endif
323
324 evio_stop (&sigev);
325 close (sigpipe [0]);
326 close (sigpipe [1]);
327 pipe (sigpipe);
328 siginit ();
329}
330
331/*****************************************************************************/
332
333static ev_hook hooks [EVHOOK_NUM];
334
335void
336ev_hook_register (int type, ev_hook hook)
337{
338 hooks [type] = hook;
339}
340
341void
342ev_hook_unregister (int type, ev_hook hook)
343{
344 hooks [type] = 0;
345}
346
347static void
348hook_call (int type)
349{
350 if (hooks [type])
351 hooks [type] ();
242} 352}
243 353
244static void 354static void
245fd_reify (void) 355fd_reify (void)
246{ 356{
362 double block; 472 double block;
363 ev_loop_done = flags & EVLOOP_ONESHOT; 473 ev_loop_done = flags & EVLOOP_ONESHOT;
364 474
365 do 475 do
366 { 476 {
477 hook_call (EVHOOK_PREPOLL);
478
367 /* update fd-related kernel structures */ 479 /* update fd-related kernel structures */
368 fd_reify (); 480 fd_reify ();
369 481
370 /* calculate blocking time */ 482 /* calculate blocking time */
371 if (flags & EVLOOP_NONBLOCK) 483 if (flags & EVLOOP_NONBLOCK)
392 method_poll (block); 504 method_poll (block);
393 505
394 /* update ev_now, do magic */ 506 /* update ev_now, do magic */
395 time_update (); 507 time_update ();
396 508
509 hook_call (EVHOOK_POSTPOLL);
510
397 /* put pending timers into pendign queue and reschedule them */ 511 /* put pending timers into pendign queue and reschedule them */
398 /* absolute timers first */ 512 /* absolute timers first */
399 timers_reify (atimers, atimercnt, ev_now); 513 timers_reify (atimers, atimercnt, ev_now);
400 /* relative timers second */ 514 /* relative timers second */
401 timers_reify (rtimers, rtimercnt, now); 515 timers_reify (rtimers, rtimercnt, now);
403 call_pending (); 517 call_pending ();
404 } 518 }
405 while (!ev_loop_done); 519 while (!ev_loop_done);
406} 520}
407 521
522/*****************************************************************************/
523
408static void 524static void
409wlist_add (struct ev_watcher_list **head, struct ev_watcher_list *elem) 525wlist_add (struct ev_watcher_list **head, struct ev_watcher_list *elem)
410{ 526{
411 elem->next = *head; 527 elem->next = *head;
412 *head = elem; 528 *head = elem;
441 pendings [w->pending - 1].w = 0; 557 pendings [w->pending - 1].w = 0;
442 558
443 w->active = 0; 559 w->active = 0;
444 /* nop */ 560 /* nop */
445} 561}
562
563/*****************************************************************************/
446 564
447void 565void
448evio_start (struct ev_io *w) 566evio_start (struct ev_io *w)
449{ 567{
450 if (ev_is_active (w)) 568 if (ev_is_active (w))
536 if (ev_is_active (w)) 654 if (ev_is_active (w))
537 return; 655 return;
538 656
539 ev_start ((struct ev_watcher *)w, 1); 657 ev_start ((struct ev_watcher *)w, 1);
540 array_needsize (signals, signalmax, w->signum, signals_init); 658 array_needsize (signals, signalmax, w->signum, signals_init);
541 wlist_add ((struct ev_watcher_list **)&signals [w->signum - 1], (struct ev_watcher_list *)w); 659 wlist_add ((struct ev_watcher_list **)&signals [w->signum - 1].head, (struct ev_watcher_list *)w);
660
661 if (!w->next)
662 {
663 struct sigaction sa;
664 sa.sa_handler = sighandler;
665 sigfillset (&sa.sa_mask);
666 sa.sa_flags = 0;
667 sigaction (w->signum, &sa, 0);
668 }
542} 669}
543 670
544void 671void
545evsignal_stop (struct ev_signal *w) 672evsignal_stop (struct ev_signal *w)
546{ 673{
547 if (!ev_is_active (w)) 674 if (!ev_is_active (w))
548 return; 675 return;
549 676
550 wlist_del ((struct ev_watcher_list **)&signals [w->signum - 1], (struct ev_watcher_list *)w); 677 wlist_del ((struct ev_watcher_list **)&signals [w->signum - 1].head, (struct ev_watcher_list *)w);
551 ev_stop ((struct ev_watcher *)w); 678 ev_stop ((struct ev_watcher *)w);
679
680 if (!signals [w->signum - 1].head)
681 signal (w->signum, SIG_DFL);
552} 682}
553 683
554/*****************************************************************************/ 684/*****************************************************************************/
555#if 1 685#if 1
556 686
564ocb (struct ev_timer *w, int revents) 694ocb (struct ev_timer *w, int revents)
565{ 695{
566 //fprintf (stderr, "timer %f,%f (%x) (%f) d%p\n", w->at, w->repeat, revents, w->at - ev_time (), w->data); 696 //fprintf (stderr, "timer %f,%f (%x) (%f) d%p\n", w->at, w->repeat, revents, w->at - ev_time (), w->data);
567 evtimer_stop (w); 697 evtimer_stop (w);
568 evtimer_start (w); 698 evtimer_start (w);
699}
700
701static void
702scb (struct ev_signal *w, int revents)
703{
704 fprintf (stderr, "signal %x,%d\n", revents, w->signum);
569} 705}
570 706
571int main (void) 707int main (void)
572{ 708{
573 struct ev_io sin; 709 struct ev_io sin;
596 struct ev_timer t1; 732 struct ev_timer t1;
597 evw_init (&t1, ocb, 0); 733 evw_init (&t1, ocb, 0);
598 evtimer_set_abs (&t1, 5, 10); 734 evtimer_set_abs (&t1, 5, 10);
599 evtimer_start (&t1); 735 evtimer_start (&t1);
600 736
737 struct ev_signal sig;
738 evw_init (&sig, scb, 65535);
739 evsignal_set (&sig, SIGQUIT);
740 evsignal_start (&sig);
741
601 ev_loop (0); 742 ev_loop (0);
602 743
603 return 0; 744 return 0;
604} 745}
605 746

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines