patch-2.3.99-pre3 linux/fs/fifo.c
Next file: linux/fs/hfs/inode.c
Previous file: linux/fs/fat/inode.c
Back to the patch index
Back to the overall index
- Lines: 127
- Date:
Tue Mar 21 12:47:12 2000
- Orig file:
v2.3.99-pre2/linux/fs/fifo.c
- Orig date:
Tue Mar 7 14:32:26 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/fs/fifo.c linux/fs/fifo.c
@@ -12,6 +12,21 @@
#include <linux/mm.h>
#include <linux/malloc.h>
+static void wait_for_partner(struct inode* inode, unsigned int* cnt)
+{
+ int cur = *cnt;
+ while(cur == *cnt) {
+ pipe_wait(inode);
+ if(signal_pending(current))
+ break;
+ }
+}
+
+static void wake_up_partner(struct inode* inode)
+{
+ wake_up_interruptible(PIPE_WAIT(*inode));
+}
+
static int fifo_open(struct inode *inode, struct file *filp)
{
int ret;
@@ -20,29 +35,12 @@
if (down_interruptible(PIPE_SEM(*inode)))
goto err_nolock_nocleanup;
- if (! inode->i_pipe) {
- unsigned long page;
- struct pipe_inode_info *info;
-
- info = kmalloc(sizeof(struct pipe_inode_info),GFP_KERNEL);
-
+ if (!inode->i_pipe) {
ret = -ENOMEM;
- if (!info)
+ if(!pipe_new(inode))
goto err_nocleanup;
- page = __get_free_page(GFP_KERNEL);
- if (!page) {
- kfree(info);
- goto err_nocleanup;
- }
-
- inode->i_pipe = info;
-
- init_waitqueue_head(PIPE_WAIT(*inode));
- PIPE_BASE(*inode) = (char *) page;
- PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
- PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
- PIPE_WAITING_WRITERS(*inode) = PIPE_WAITING_READERS(*inode) = 0;
}
+ filp->f_version = 0;
switch (filp->f_mode) {
case 1:
@@ -51,27 +49,23 @@
* POSIX.1 says that O_NONBLOCK means return with the FIFO
* opened, even when there is no process writing the FIFO.
*/
- filp->f_op = &connecting_fifo_fops;
+ filp->f_op = &read_fifo_fops;
+ PIPE_RCOUNTER(*inode)++;
if (PIPE_READERS(*inode)++ == 0)
- wake_up_interruptible(PIPE_WAIT(*inode));
+ wake_up_partner(inode);
- if (!(filp->f_flags & O_NONBLOCK)) {
- while (!PIPE_WRITERS(*inode)) {
- if (signal_pending(current))
+ if (!PIPE_WRITERS(*inode)) {
+ if ((filp->f_flags & O_NONBLOCK)) {
+ /* suppress POLLHUP until we have
+ * seen a writer */
+ filp->f_version = PIPE_WCOUNTER(*inode);
+ } else
+ {
+ wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
+ if(signal_pending(current))
goto err_rd;
- up(PIPE_SEM(*inode));
- interruptible_sleep_on(PIPE_WAIT(*inode));
-
- /* Note that using down_interruptible here
- and similar places below is pointless,
- since we have to acquire the lock to clean
- up properly. */
- down(PIPE_SEM(*inode));
}
}
-
- if (PIPE_WRITERS(*inode))
- filp->f_op = &read_fifo_fops;
break;
case 2:
@@ -85,15 +79,14 @@
goto err;
filp->f_op = &write_fifo_fops;
+ PIPE_WCOUNTER(*inode)++;
if (!PIPE_WRITERS(*inode)++)
- wake_up_interruptible(PIPE_WAIT(*inode));
+ wake_up_partner(inode);
- while (!PIPE_READERS(*inode)) {
+ if (!PIPE_READERS(*inode)) {
+ wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
if (signal_pending(current))
goto err_wr;
- up(PIPE_SEM(*inode));
- interruptible_sleep_on(PIPE_WAIT(*inode));
- down(PIPE_SEM(*inode));
}
break;
@@ -108,8 +101,10 @@
PIPE_READERS(*inode)++;
PIPE_WRITERS(*inode)++;
+ PIPE_RCOUNTER(*inode)++;
+ PIPE_WCOUNTER(*inode)++;
if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
- wake_up_interruptible(PIPE_WAIT(*inode));
+ wake_up_partner(inode);
break;
default:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)