mirror of /home/gitosis/repositories/libev.git
better fork
parent
66df0f5347
commit
b54f6e9ced
60
ev.c
60
ev.c
|
@ -155,21 +155,24 @@ volatile double SIGFPE_REQ = 0.0f;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void (*syserr_cb)(void);
|
||||
static void (*syserr_cb)(const char *msg);
|
||||
|
||||
void ev_set_syserr_cb (void (*cb)(void))
|
||||
void ev_set_syserr_cb (void (*cb)(const char *msg))
|
||||
{
|
||||
syserr_cb = cb;
|
||||
}
|
||||
|
||||
static void
|
||||
syserr (void)
|
||||
syserr (const char *msg)
|
||||
{
|
||||
if (!msg)
|
||||
msg = "(libev) system error";
|
||||
|
||||
if (syserr_cb)
|
||||
syserr_cb ();
|
||||
syserr_cb (msg);
|
||||
else
|
||||
{
|
||||
perror ("libev");
|
||||
perror (msg);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +383,7 @@ fd_reify (EV_P)
|
|||
static void
|
||||
fd_change (EV_P_ int fd)
|
||||
{
|
||||
if (anfds [fd].reify || fdchangecnt < 0)
|
||||
if (anfds [fd].reify)
|
||||
return;
|
||||
|
||||
anfds [fd].reify = 1;
|
||||
|
@ -428,7 +431,7 @@ fd_enomem (EV_P)
|
|||
}
|
||||
}
|
||||
|
||||
/* susually called after fork if method needs to re-arm all fds from scratch */
|
||||
/* usually called after fork if method needs to re-arm all fds from scratch */
|
||||
static void
|
||||
fd_rearm_all (EV_P)
|
||||
{
|
||||
|
@ -695,6 +698,9 @@ loop_init (EV_P_ int methods)
|
|||
#if EV_USE_SELECT
|
||||
if (!method && (methods & EVMETHOD_SELECT)) method = select_init (EV_A_ methods);
|
||||
#endif
|
||||
|
||||
ev_watcher_init (&sigev, sigcb);
|
||||
ev_set_priority (&sigev, EV_MAXPRI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,19 +736,34 @@ loop_destroy (EV_P)
|
|||
array_free (check, );
|
||||
|
||||
method = 0;
|
||||
/*TODO*/
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
loop_fork (EV_P)
|
||||
{
|
||||
/*TODO*/
|
||||
#if EV_USE_EPOLL
|
||||
if (method == EVMETHOD_EPOLL ) epoll_fork (EV_A);
|
||||
#endif
|
||||
#if EV_USE_KQUEUE
|
||||
if (method == EVMETHOD_KQUEUE) kqueue_fork (EV_A);
|
||||
#endif
|
||||
|
||||
if (ev_is_active (&sigev))
|
||||
{
|
||||
/* default loop */
|
||||
|
||||
ev_ref (EV_A);
|
||||
ev_io_stop (EV_A_ &sigev);
|
||||
close (sigpipe [0]);
|
||||
close (sigpipe [1]);
|
||||
|
||||
while (pipe (sigpipe))
|
||||
syserr ("(libev) error creating pipe");
|
||||
|
||||
siginit (EV_A);
|
||||
}
|
||||
|
||||
postfork = 0;
|
||||
}
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
|
@ -771,7 +792,7 @@ ev_loop_destroy (EV_P)
|
|||
void
|
||||
ev_loop_fork (EV_P)
|
||||
{
|
||||
loop_fork (EV_A);
|
||||
postfork = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -804,8 +825,6 @@ ev_default_loop (int methods)
|
|||
|
||||
if (ev_method (EV_A))
|
||||
{
|
||||
ev_watcher_init (&sigev, sigcb);
|
||||
ev_set_priority (&sigev, EV_MAXPRI);
|
||||
siginit (EV_A);
|
||||
|
||||
#ifndef WIN32
|
||||
|
@ -848,15 +867,8 @@ ev_default_fork (void)
|
|||
struct ev_loop *loop = default_loop;
|
||||
#endif
|
||||
|
||||
loop_fork (EV_A);
|
||||
|
||||
ev_io_stop (EV_A_ &sigev);
|
||||
close (sigpipe [0]);
|
||||
close (sigpipe [1]);
|
||||
pipe (sigpipe);
|
||||
|
||||
ev_ref (EV_A); /* signal watcher */
|
||||
siginit (EV_A);
|
||||
if (method)
|
||||
postfork = 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1044,6 +1056,10 @@ ev_loop (EV_P_ int flags)
|
|||
call_pending (EV_A);
|
||||
}
|
||||
|
||||
/* we might have forked, so reify kernel state if necessary */
|
||||
if (expect_false (postfork))
|
||||
loop_fork (EV_A);
|
||||
|
||||
/* update fd-related kernel structures */
|
||||
fd_reify (EV_A);
|
||||
|
||||
|
|
2
ev.h
2
ev.h
|
@ -241,7 +241,7 @@ void ev_set_allocator (void *(*cb)(void *ptr, long size));
|
|||
* retryable syscall error
|
||||
* (such as failed select, poll, epoll_wait)
|
||||
*/
|
||||
void ev_set_syserr_cb (void (*cb)(void));
|
||||
void ev_set_syserr_cb (void (*cb)(const char *msg));
|
||||
|
||||
# if EV_MULTIPLICITY
|
||||
/* the default loop is the only one that handles signals and child watchers */
|
||||
|
|
13
ev_epoll.c
13
ev_epoll.c
|
@ -57,7 +57,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|||
if (eventcnt < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
syserr ();
|
||||
syserr ("(libev) epoll_wait");
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -110,7 +110,16 @@ epoll_destroy (EV_P)
|
|||
static void
|
||||
epoll_fork (EV_P)
|
||||
{
|
||||
epoll_fd = epoll_create (256);
|
||||
for (;;)
|
||||
{
|
||||
epoll_fd = epoll_create (256);
|
||||
|
||||
if (epoll_fd >= 0)
|
||||
break;
|
||||
|
||||
syserr ("(libev) epoll_create");
|
||||
}
|
||||
|
||||
fcntl (epoll_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
fd_rearm_all (EV_A);
|
||||
|
|
13
ev_kqueue.c
13
ev_kqueue.c
|
@ -87,7 +87,7 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
|
|||
if (res < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
syserr ();
|
||||
syserr ("(libev) kevent");
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -185,7 +185,16 @@ kqueue_destroy (EV_P)
|
|||
static void
|
||||
kqueue_fork (EV_P)
|
||||
{
|
||||
kqueue_fd = kqueue ();
|
||||
for (;;)
|
||||
{
|
||||
kqueue_fd = kqueue ();
|
||||
|
||||
if (kqueue_fd >= 0)
|
||||
break;
|
||||
|
||||
syserr ("(libev) kqueue");
|
||||
}
|
||||
|
||||
fcntl (kqueue_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* re-register interest in fds */
|
||||
|
|
|
@ -85,7 +85,7 @@ poll_poll (EV_P_ ev_tstamp timeout)
|
|||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
syserr ();
|
||||
syserr ("(libev) poll");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ select_poll (EV_P_ ev_tstamp timeout)
|
|||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
syserr ();
|
||||
syserr ("(libev) select");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ VARx(ev_tstamp, method_fudge) /* assumed typical timer resolution */
|
|||
VAR (method_modify, void (*method_modify)(EV_P_ int fd, int oev, int nev))
|
||||
VAR (method_poll , void (*method_poll)(EV_P_ ev_tstamp timeout))
|
||||
|
||||
VARx(int, postfork) /* true if we need to recreate kernel state after fork */
|
||||
VARx(int, activecnt) /* number of active events */
|
||||
|
||||
#if EV_USE_SELECT || EV_GENWRAP
|
||||
|
|
Loading…
Reference in New Issue