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

Comparing libev/ev.c (file contents):
Revision 1.21 by root, Wed Oct 31 18:37:38 2007 UTC vs.
Revision 1.23 by root, Wed Oct 31 20:10:17 2007 UTC

36 36
37#include <stdio.h> 37#include <stdio.h>
38 38
39#include <assert.h> 39#include <assert.h>
40#include <errno.h> 40#include <errno.h>
41#include <sys/types.h>
42#include <sys/wait.h>
41#include <sys/time.h> 43#include <sys/time.h>
42#include <time.h> 44#include <time.h>
43 45
44#ifndef HAVE_MONOTONIC 46#ifndef HAVE_MONOTONIC
45# ifdef CLOCK_MONOTONIC 47# ifdef CLOCK_MONOTONIC
59# define HAVE_REALTIME 1 /* posix requirement, but might be slower */ 61# define HAVE_REALTIME 1 /* posix requirement, but might be slower */
60#endif 62#endif
61 63
62#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ 64#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
63#define MAX_BLOCKTIME 60. 65#define MAX_BLOCKTIME 60.
66#define PID_HASHSIZE 16 /* size of pid hahs table, must be power of two */
64 67
65#include "ev.h" 68#include "ev.h"
66 69
67typedef struct ev_watcher *W; 70typedef struct ev_watcher *W;
68typedef struct ev_watcher_list *WL; 71typedef struct ev_watcher_list *WL;
110} 113}
111 114
112#define array_needsize(base,cur,cnt,init) \ 115#define array_needsize(base,cur,cnt,init) \
113 if ((cnt) > cur) \ 116 if ((cnt) > cur) \
114 { \ 117 { \
115 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 \
116 base = realloc (base, sizeof (*base) * (newcnt)); \ 125 base = realloc (base, sizeof (*base) * (newcnt)); \
117 init (base + cur, newcnt - cur); \ 126 init (base + cur, newcnt - cur); \
118 cur = newcnt; \ 127 cur = newcnt; \
119 } 128 }
120 129
332static struct ev_check **checks; 341static struct ev_check **checks;
333static int checkmax, checkcnt; 342static int checkmax, checkcnt;
334 343
335/*****************************************************************************/ 344/*****************************************************************************/
336 345
346static struct ev_child *childs [PID_HASHSIZE];
347static struct ev_signal childev;
348
349#ifndef WCONTINUED
350# define WCONTINUED 0
351#endif
352
353static void
354childcb (struct ev_signal *sw, int revents)
355{
356 struct ev_child *w;
357 int pid, status;
358
359 while ((pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)) != -1)
360 for (w = childs [pid & (PID_HASHSIZE - 1)]; w; w = w->next)
361 if (w->pid == pid || w->pid == -1)
362 {
363 w->status = status;
364 event ((W)w, EV_CHILD);
365 }
366}
367
368/*****************************************************************************/
369
337#if HAVE_EPOLL 370#if HAVE_EPOLL
338# include "ev_epoll.c" 371# include "ev_epoll.c"
339#endif 372#endif
340#if HAVE_SELECT 373#if HAVE_SELECT
341# include "ev_select.c" 374# include "ev_select.c"
342#endif 375#endif
343 376
344int ev_init (int flags) 377int ev_init (int flags)
345{ 378{
379 if (!ev_method)
380 {
346#if HAVE_MONOTONIC 381#if HAVE_MONOTONIC
347 { 382 {
348 struct timespec ts; 383 struct timespec ts;
349 if (!clock_gettime (CLOCK_MONOTONIC, &ts)) 384 if (!clock_gettime (CLOCK_MONOTONIC, &ts))
350 have_monotonic = 1; 385 have_monotonic = 1;
351 } 386 }
352#endif 387#endif
353 388
354 ev_now = ev_time (); 389 ev_now = ev_time ();
355 now = get_clock (); 390 now = get_clock ();
356 diff = ev_now - now; 391 diff = ev_now - now;
357 392
358 if (pipe (sigpipe)) 393 if (pipe (sigpipe))
359 return 0; 394 return 0;
360 395
361 ev_method = EVMETHOD_NONE; 396 ev_method = EVMETHOD_NONE;
362#if HAVE_EPOLL 397#if HAVE_EPOLL
363 if (ev_method == EVMETHOD_NONE) epoll_init (flags); 398 if (ev_method == EVMETHOD_NONE) epoll_init (flags);
364#endif 399#endif
365#if HAVE_SELECT 400#if HAVE_SELECT
366 if (ev_method == EVMETHOD_NONE) select_init (flags); 401 if (ev_method == EVMETHOD_NONE) select_init (flags);
367#endif 402#endif
368 403
369 if (ev_method) 404 if (ev_method)
370 { 405 {
371 evw_init (&sigev, sigcb); 406 evw_init (&sigev, sigcb);
372 siginit (); 407 siginit ();
408
409 evsignal_init (&childev, childcb, SIGCHLD);
410 evsignal_start (&childev);
411 }
373 } 412 }
374 413
375 return ev_method; 414 return ev_method;
376} 415}
377 416
876 ev_clear ((W)w); 915 ev_clear ((W)w);
877 if (ev_is_active (w)) 916 if (ev_is_active (w))
878 return; 917 return;
879 918
880 checks [w->active - 1] = checks [--checkcnt]; 919 checks [w->active - 1] = checks [--checkcnt];
920 ev_stop ((W)w);
921}
922
923void evchild_start (struct ev_child *w)
924{
925 if (ev_is_active (w))
926 return;
927
928 ev_start ((W)w, 1);
929 wlist_add ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w);
930}
931
932void evchild_stop (struct ev_child *w)
933{
934 ev_clear ((W)w);
935 if (ev_is_active (w))
936 return;
937
938 wlist_del ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w);
881 ev_stop ((W)w); 939 ev_stop ((W)w);
882} 940}
883 941
884/*****************************************************************************/ 942/*****************************************************************************/
885 943

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines