forked from nuttx/nuttx-update
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
This commit is contained in:
parent
759ba256e8
commit
28db0e083a
5 changed files with 36 additions and 3 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -1025,6 +1025,7 @@ nuttx-0.3.12 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||
* 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 <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue