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

Reply via email to