diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-07-26 14:24:17 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-07-26 14:24:17 +0000 |
commit | 9c61d1e4e2d425c03af542f2ff40e7b00575b582 (patch) | |
tree | 0304edd450687379182331d0e1ae52347c4134c0 /nuttx/drivers/pipe-common.c | |
parent | 3ebe09f0ac8d3be70fda8df613db3c6c9f695db4 (diff) | |
download | px4-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.c | 27 |
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; |