PERFORCE change 164492 for review

Zhao Shuai zhaoshuai at FreeBSD.org
Tue Jun 16 12:14:50 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=164492

Change 164492 by zhaoshuai at zhaoshuai on 2009/06/16 12:14:45

	fix fifo_kqfilter_f()

Affected files ...

.. //depot/projects/soc2009/fifo/sys/fs/fifofs/fifo_vnops.c#15 edit
.. //depot/projects/soc2009/fifo/sys/kern/subr_pipe.c#6 edit

Differences ...

==== //depot/projects/soc2009/fifo/sys/fs/fifofs/fifo_vnops.c#15 (text+ko) ====

@@ -91,9 +91,16 @@
 static vop_pathconf_t	fifo_pathconf;
 static vop_advlock_t	fifo_advlock;
 
+static void	filt_fifodetach(struct knote *kn);
+static int	filt_fiforead(struct knote *kn, long hint);
+static int	filt_fifowrite(struct knote *kn, long hint);
 static void	filt_fifodetach_notsup(struct knote *kn);
 static int	filt_fifo_notsup(struct knote *kn, long hint);
 
+static struct filterops fiforead_filtops =
+	{ 1, NULL, filt_fifodetach, filt_fiforead };
+static struct filterops fifowrite_filtops =
+	{ 1, NULL, filt_fifodetach, filt_fifowrite };
 static struct filterops fifo_notsup_filtops = 
 	{ 1, NULL, filt_fifodetach_notsup, filt_fifo_notsup };
 
@@ -503,6 +510,7 @@
 fifo_kqfilter_f(struct file *fp, struct knote *kn)
 {
 	struct fifoinfo *fip = fp->f_data;
+	struct pipe *rpipe = fip->fi_rpipe;
 
 	/*
 	 * If a filter is requested that is not supported by this file
@@ -520,18 +528,86 @@
 
 	switch (kn->kn_filter) {
 	case EVFILT_READ:
-		return (generic_pipe_kqfilter(fip->fi_rpipe, kn));
-
+		kn->kn_fop = &fiforead_filtops;
+		break;
 	case EVFILT_WRITE:
-		return (generic_pipe_kqfilter(fip->fi_wpipe, kn));
-
+		kn->kn_fop = &fifowrite_filtops;
+		PIPE_LOCK(rpipe);
+		if (rpipe->pipe_present != PIPE_ACTIVE) {
+			/* other end of pipe has been closed */
+			PIPE_UNLOCK(rpipe);
+			return (EPIPE);
+		}
+		PIPE_UNLOCK(rpipe);
+		break;
 	default:
 		return (EINVAL);
 	}
 
+	kn->kn_hook = (void *)rpipe; 
+
+	PIPE_LOCK(rpipe);
+	knlist_add(&rpipe->pipe_sel.si_note, kn, 1);
+	PIPE_UNLOCK(rpipe);
+
 	return (0);
 }
 
+static void
+filt_fifodetach(struct knote *kn)
+{
+	struct pipe *pipe = (struct pipe *)kn->kn_hook;
+
+	PIPE_LOCK(pipe);
+	knlist_remove(&pipe->pipe_sel.si_note, kn, 1);
+	PIPE_UNLOCK(pipe);
+}
+
+static int
+filt_fiforead(struct knote *kn, long hint)
+{
+	struct pipe *rpipe = (struct pipe *)kn->kn_hook;
+	struct pipe *wpipe = rpipe->pipe_peer;
+	int ret;
+
+	PIPE_LOCK(rpipe);
+	kn->kn_data = rpipe->pipe_buffer.cnt;
+	if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW))
+		kn->kn_data = rpipe->pipe_map.cnt;
+
+	if ((rpipe->pipe_state & PIPE_EOF) ||
+	    wpipe->pipe_present != PIPE_ACTIVE ||
+	    (wpipe->pipe_state & PIPE_EOF)) {
+		kn->kn_flags |= EV_EOF;
+		PIPE_UNLOCK(rpipe);
+		return (1);
+	}
+	ret = kn->kn_data > 0;
+	PIPE_UNLOCK(rpipe);
+	return ret;
+}
+
+static int
+filt_fifowrite(struct knote *kn, long hint)
+{
+	struct pipe *wpipe = (struct pipe *)kn->kn_hook;
+
+	PIPE_LOCK(wpipe);
+	if (wpipe->pipe_present != PIPE_ACTIVE ||
+	    (wpipe->pipe_state & PIPE_EOF)) {
+		kn->kn_data = 0;
+		kn->kn_flags |= EV_EOF;
+		PIPE_UNLOCK(wpipe);
+		return (1);
+	}
+	kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
+	if (wpipe->pipe_state & PIPE_DIRECTW)
+		kn->kn_data = 0;
+
+	PIPE_UNLOCK(wpipe);
+	return (kn->kn_data >= PIPE_BUF);
+}
+
 static void 
 filt_fifodetach_notsup(struct knote *kn)
 {

==== //depot/projects/soc2009/fifo/sys/kern/subr_pipe.c#6 (text+ko) ====

@@ -1378,7 +1378,7 @@
 	cpipe->pipe_present = PIPE_FINALIZED;
 	knlist_destroy(&cpipe->pipe_sel.si_note);
 	
-	/* XXX: is it OK to put is here? */
+	/* XXX: is it OK to put it here? */
 	funsetown(&cpipe->pipe_sigio);
 
 	/*


More information about the p4-projects mailing list