From owner-freebsd-hackers Tue Feb 27 13:28:43 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from hda.hda.com (host65.hda.com [63.104.68.65]) by hub.freebsd.org (Postfix) with ESMTP id 141AE37B719 for ; Tue, 27 Feb 2001 13:28:31 -0800 (PST) (envelope-from dufault@hda.hda.com) Received: (from dufault@localhost) by hda.hda.com (8.11.1/8.11.1) id f1RLQNH24622; Tue, 27 Feb 2001 16:26:23 -0500 (EST) (envelope-from dufault) From: Peter Dufault Message-Id: <200102272126.f1RLQNH24622@hda.hda.com> Subject: Re: Where can I find out rules on blocking in threads? In-Reply-To: <200102272051.MAA42206@akira.lanfear.com> from Marc W at "Feb 27, 2001 12:51:11 pm" To: Marc W Date: Tue, 27 Feb 2001 16:26:23 -0500 (EST) Cc: freebsd-hackers@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL61 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > it gets worse -- when i change my loop to be: > > while (1) { > > fifo = open(fifoPath, O_RDONLY | O_NONBLOCK); > cread = read(fifo, buf, sizeof(buf)); > if (cread > 0) do_something(); > close(fifo); > usleep(100000); > } > > anybody who tries to open the write end of the fifo ends up hanging > .. It's a little messier than I hoped. As long as no one has opened the FIFO for write read returns a zero with errno clear. If you don't have time slicing turned on for the threads you'll hang forever. You'll have to do something like this: #include #include #include #include #include #include #include struct threadstuff { int rfid, wfid; const char *name; }; static void * reader(void *arg) { int flags; ssize_t r; char buff[32]; int cr; struct threadstuff *pts = (struct threadstuff *)arg; fprintf(stderr, "Opening %s for read, non-blocking...\n", pts->name); pts->rfid = open(pts->name, O_RDONLY | O_NONBLOCK); fprintf(stderr, "reader got fid %d, setting to blocking...\n", pts->rfid); (void)fcntl(pts->rfid, F_GETFL, &flags); flags &= ~O_NONBLOCK; (void)fcntl(pts->rfid, F_SETFL, &flags); fprintf(stderr, "Trying to read something from the FIFO...\n"); cr = 0; /* * You better have round robin turned on here or be sure * the writer is of higher priority or you'll just buzz * away the CPU. */ do { errno = 0; r = read(pts->rfid, buff, sizeof(buff) - 1); if (errno == 0 && r == 0) { /* No one has the FIFO open for write. * You should delay here (or preferably synchronize) * to avoid busy waiting. */ cr++; fprintf(stderr, "%s(%3d) No writer yet.\r", ((cr % 5) == 1) ? "\n" : "", cr); } } while (r == 0); if (r < 0) { perror("Read of FIFO"); } else { buff[r] = 0; fprintf(stderr, "Read \"%s\".\n", buff); } return 0; } static void * writer(void *arg) { char something[] = "Something"; struct threadstuff *pts = (struct threadstuff *)arg; fprintf(stderr, "Opening %s for write\n", pts->name); pts->wfid = open(pts->name, O_WRONLY); fprintf(stderr, "writer got fid %d.\n", pts->wfid); write(pts->wfid, something, sizeof(something)); return 0; } int main(int ac, char *av[]) { pthread_t r, w; void *value; struct threadstuff ts; ts.name = "./my_fifo"; ts.rfid = ts.wfid = -1; (void)unlink(ts.name); (void)mkfifo(ts.name, 0666); pthread_create(&r, 0, reader, (void *)&ts); pthread_create(&w, 0, writer, (void *)&ts); pthread_join(r, &value); pthread_join(w, &value); if (ts.rfid != -1) (void)close(ts.rfid); if (ts.wfid != -1) (void)close(ts.wfid); return 0; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message