summaryrefslogtreecommitdiff
path: root/nuttx/drivers/pipe-common.c
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/drivers/pipe-common.c
parent3ebe09f0ac8d3be70fda8df613db3c6c9f695db4 (diff)
downloadpx4-nuttx-9c61d1e4e2d425c03af542f2ff40e7b00575b582.tar.gz
px4-nuttx-9c61d1e4e2d425c03af542f2ff40e7b00575b582.tar.bz2
px4-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/drivers/pipe-common.c')
-rw-r--r--nuttx/drivers/pipe-common.c27
1 files changed, 27 insertions, 0 deletions
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;