On Fri, Jun 16, 2017 at 08:16:19AM +0000, Luke Small wrote:

> I made a simple case. I need to have a kevent wait for both incoming socket
> communications and for the forked process to finish its run evaluating
> shared data.
> I show that it fails to merely wait for NOTE_EXIT calls and I'd guess
> making the kernel aware that the process died.
> 
> limit_test.c shows that there is a fork error when it runs a while even if
> it waits for the forked process to die, where it doesn't occur by simply
> using wait(2), which is in comments below it.

I do not see a fork error, but a kevent error:

...
24
25
a.out: kevent: No such process

You code indeed has a race condition: the child proces might already
have exited the moment you call kevent.

wait(2) is a bit different: it allows for waiting on a proces that already
has died but hasn't been waited for yet. The child process will have the
zombie state in the meantime.

        -Otto


> #include <err.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/event.h>
> #include <sys/socket.h>
> #include <sys/wait.h>
> 
> int main()
> {
>     int i;
>     int k;
>     int kq;
>     int integer;
>     struct kevent ke;
>     
>     kq = kqueue();
>     if (kq == -1)
>           err(1, "kq!");
>           
>     for (i = 0; i < 2000; ++i)
>     {
> 
>       integer = fork();
>       switch(integer)
>       {
>               case -1:
>                       err(1, "fork!");
>               case 0:
>                       _exit(0);
>               default:
>                       break;
>       }
> 
>       EV_SET(&ke, integer, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, 
> NULL);
>       if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
>               err(1, "kevent");
>       
>       
>       k = kevent(kq, NULL, 0, &ke, 1, NULL);
>       if (k == -1)
>               err(1, "k == -1");
>       if(ke.flags & EV_ERROR)
>               err(1, "EV_ERROR");
> 
>       printf("%d\n", i);
>     }
> }
> 
> /*
> int main()
> {
>     int i;
>     int integer;
>     for (i = 0; i < 2000; ++i)
>     {
>       integer = fork();
>       switch(integer)
>       {
>               case -1:
>                       err(1, "fork!");
>               case 0:
>                       _exit(0);
>               default:
>                       break;
>       }
>       wait(NULL);
>       printf("%d\n", i);
>     }
> }
> */

Reply via email to