summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-07-26 14:24:17 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-07-26 14:24:17 +0000
commit9c61d1e4e2d425c03af542f2ff40e7b00575b582 (patch)
tree0304edd450687379182331d0e1ae52347c4134c0 /nuttx
parent3ebe09f0ac8d3be70fda8df613db3c6c9f695db4 (diff)
downloadnuttx-9c61d1e4e2d425c03af542f2ff40e7b00575b582.tar.gz
nuttx-9c61d1e4e2d425c03af542f2ff40e7b00575b582.tar.bz2
nuttx-9c61d1e4e2d425c03af542f2ff40e7b00575b582.zip
O_RDONLY open on FIFO blocks until writer opens
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@781 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog1
-rw-r--r--nuttx/Documentation/NuttX.html1
-rw-r--r--nuttx/drivers/fifo.c8
-rw-r--r--nuttx/drivers/pipe-common.c27
-rw-r--r--nuttx/examples/pipe/pipe_main.c2
5 files changed, 36 insertions, 3 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index fc33a6d81..8f6313bce 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -376,4 +376,5 @@
* Correct bug in recursive mutex logic
* Add mkfifo()
* Add pipe() and test for both pipes and fifos
+ * Attempts to open a FIFO will now block until there is at least one writer
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 70b781c8e..5d3c130bc 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -1025,6 +1025,7 @@ nuttx-0.3.12 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* Correct bug in recursive mutex logic
* Add mkfifo()
* Add pipe() and test for both pipes and fifos
+ * Attempts to open a FIFO will now block until there is at least one writer
pascal-0.1.3 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
diff --git a/nuttx/drivers/fifo.c b/nuttx/drivers/fifo.c
index 88ab1deb6..9ad64dbcb 100644
--- a/nuttx/drivers/fifo.c
+++ b/nuttx/drivers/fifo.c
@@ -96,8 +96,12 @@ static struct file_operations fifo_fops =
* Once the FIFO has been created by mkfifo(), any thread can open it for
* reading or writing, in the same way as an ordinary file. However, it must
* have been opened from both reading and writing before input or output
- * can be performed. Unlike other mkfifo() implementations, this one will
- * NOT block when the FIFO is opened on only one end.
+ * can be performed. This FIFO implementation will block all attempts to
+ * open a FIFO read-only until at least one thread has opened the FIFO for
+ * writing.
+ *
+ * If all threads that write to the FIFO have closed, subsequent calls to
+ * read() on the FIFO will return 0 (end-of-file).
*
* Inputs:
* pathname - The full path to the FIFO instance to attach to or to create
diff --git a/nuttx/drivers/pipe-common.c b/nuttx/drivers/pipe-common.c
index 1004d15f8..ab6b7d380 100644
--- a/nuttx/drivers/pipe-common.c
+++ b/nuttx/drivers/pipe-common.c
@@ -139,6 +139,7 @@ int pipecommon_open(FAR struct file *filep)
{
struct inode *inode = filep->f_inode;
struct pipe_dev_s *dev = inode->i_private;
+ int sval;
/* Some sanity checking */
#if CONFIG_DEBUG
@@ -160,11 +161,37 @@ int pipecommon_open(FAR struct file *filep)
if ((filep->f_oflags & O_WROK) != 0)
{
dev->s.d_nwriters++;
+
+ /* If this this is the first writer, then the read semaphore indicates the
+ * number of readers waiting for the first writer. Wake them all up.
+ */
+ if (dev->s.d_nwriters == 1)
+ {
+ while (sem_getvalue(&dev->s.d_rdsem, &sval) == 0 && sval < 0)
+ {
+ sem_post(&dev->s.d_rdsem);
+ }
+ }
}
/* If opened for read-only, then wait for at least one writer on the pipe */
+ sched_lock();
(void)sem_post(&dev->s.d_bfsem);
+ if ((filep->f_oflags & O_RDWR) != O_RDONLY && dev->s.d_nwriters < 1)
+ {
+ /* NOTE: d_rdsem is normally used when the read logic waits for more
+ * data to be written. But until the first writer has opened the
+ * pipe, the meaning is different: it is used prevent O_RDONLY open
+ * calls from returning until there is at least one writer on the pipe.
+ * This is required both by spec and also because it prevents
+ * subsequent read() calls from returning end-of-file because there is
+ * no writer on the pipe.
+ */
+
+ pipecommon_semtake(&dev->s.d_rdsem);
+ }
+ sched_unlock();
return OK;
}
return ERROR;
diff --git a/nuttx/examples/pipe/pipe_main.c b/nuttx/examples/pipe/pipe_main.c
index 5b3874171..eadad0562 100644
--- a/nuttx/examples/pipe/pipe_main.c
+++ b/nuttx/examples/pipe/pipe_main.c
@@ -127,7 +127,7 @@ static void *reader(pthread_addr_t pvarg)
if (nbytes > NREAD_BYTES)
{
fprintf(stderr, "reader: Too many bytes read -- aborting: %d\n", nbytes);
- return (void*)3;
+ return (void*)4;
}
}
printf("reader: %d bytes read\n", nbytes);