> regarding Skip's comments: I'm not sure I completely understand.
> the parallelism is not vital. I just want to use an existing
> program (resample in this particular case) as filter to read
> some of my data, process it, and give me the result, after which
> I continue with my own thing. 

just this: in your example, if parent needs to write more than some
pipe-buf-limit (i think 32k) to child and/or if child produces output
larger than this limit and blocks on the write, it would be a problem.

i attached my example of using only one pipe which requires two
rendezvous points and customization of the slave proc; this could
have a deadlock when a child requires multiple reads to cause a write.
#include <u.h>
#include <libc.h>

void
ping(int *fd)
{
        int n, i = 0;
        char buf[1024];

        while (1) {
                i++;
                memset(buf, 'a', 1024);
                rendezvous(0, 0);

                if (i > 2) break;
                if ((n = write(fd[1], buf, sizeof(buf))) != sizeof(buf))
                        break;

                print("ping: wrote %d bytes\n", n);

                rendezvous(1,0);
                if ((n = read(fd[0], buf, sizeof(buf))) <= 0)
                        break;

                print("ping: read %d bytes\n", n);
                write(1, buf, n);
                write(1, "\n\n", 2);
        }
        close(fd[1]);
        close(fd[0]);
}

void
pong(int *fd)
{
        int n;
        char buf[1024];

        while(1) {
                rendezvous(0, 0);
                if ((n = read(fd[0], buf, sizeof(buf))) <= 0) break;

                print("pong: read %d bytes\n", n);
                write(1, buf, n);
                write(1, "\n\n", 2);

                memset(buf, 'b', sizeof(buf));
                rendezvous(1, 0);
                if ((n = write(fd[1], buf, sizeof(buf))) != sizeof(buf)) break;

                print("pong: wrote %d bytes\n", n);
        }
        close(fd[0]);
        close(fd[1]);
}

void
pingpong(void)
{
        int fd[2], pid, kid;
        
        if (pipe(fd) < 0)
                sysfatal("pipe failed: %r");

        switch (kid = rfork(RFPROC|RFFDG)) {
        case -1:
                sysfatal("fork failed: %r");
        case 0:
                pong(fd);
                break;
        default:
                ping(fd);
                while ((pid = waitpid()) != kid && pid != -1)
                        ;
                break;
        }
}

void
main(int argc, char **argv)
{
        pingpong();
        exits(nil);
}

Reply via email to