what happend if i didn't call ev_loop_fork in the child

241 Views Asked by At

I thought, if I didn't call the ev_loop_fork in the child, then the watcher in child wouldn't be triggered.

This is my code, I build the ev_loop with EVBACKEND_EPOLL and EVFLAG_NOENV flags.

So there is no EVFLAG_FORKCHECK flag.

Then I comment the ev_loop_fork call in the child.

If everything goes well, I thought the child will not trigger the timeout callback function.

But actually, the output is something like this:

$ 4980 fork 4981

$ time out at 4980

$ time out at 4981

it seemed that the watchers still has been triggered in the child, it behaved the same as call ev_loop_fork .

So what's the problem, thank you.

#include<ev.h>
#include<stdio.h>
#include<unistd.h>

void timeout_cb(EV_P_ ev_timer *w,int revents)
{
    printf("time out at %d\n", getpid());
    ev_break(EV_A_ EVBREAK_ONE);
}

int main()
{
    int ret;
    ev_timer timeout_watcher;

    struct ev_loop *loop = ev_default_loop(EVBACKEND_EPOLL | EVFLAG_NOENV);

    ev_timer_init(&timeout_watcher,timeout_cb,5.5,0.);
    ev_timer_start(loop,&timeout_watcher);
    ret = fork();
    if(ret>0) printf("%d fork %d\n",getpid(),ret);
    else if(ret==0)
    {
        //ev_loop_fork(EV_DEFAULT);
    }
    else return -1;
    ev_run(loop,0);
    return 0;
}
1

There are 1 best solutions below

0
On

The libev manual does not say that after a fork an event loop will be stopped. All it says is that to be sure that the event loop will properly work in the child, you need to call ev_loop_fork(). What's actually happening depends on the backend.

And technically, timers will even be more resilient against forks in most backends: select(), poll(), epoll(), kqueue all allow for specification of a timeout value after which these functions return in case of no event. libev uses this feature to be able to trigger timeouts when they are supposed to be triggered. So there's no need to re-register any file descriptors for timeouts to work.