I had it where it made a pipe and the child waited on a recv() before the
parent registered the kevent and closed the pipe. On my virtual machine,
this code works the same. It spawns a fork() error and my large project
makes it where no roxterm can spawn a new ksh instance.
On Fri, Jun 16, 2017 at 9:20 AM Otto Moerbeek <[email protected]> wrote:
> 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);
> > }
> > }
> > */
>
>