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);
> }
> }
> */