Commit 9fd6418a authored by Figo.zhang's avatar Figo.zhang Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (12004): poll method lose race condition



bttv-driver.c,cx23885-video.c,cx88-video.c: poll method lose race condition for capture video.

Signed-off-by: default avatarFigo.zhang <figo1802@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 1c905a45
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -3152,6 +3152,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
	struct bttv_fh *fh = file->private_data;
	struct bttv_buffer *buf;
	enum v4l2_field field;
	unsigned int rc = POLLERR;

	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
		if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
@@ -3160,9 +3161,10 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
	}

	if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
		mutex_lock(&fh->cap.vb_lock);
		/* streaming capture */
		if (list_empty(&fh->cap.stream))
			return POLLERR;
			goto err;
		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
	} else {
		/* read() capture */
@@ -3191,11 +3193,12 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
	poll_wait(file, &buf->vb.done, wait);
	if (buf->vb.state == VIDEOBUF_DONE ||
	    buf->vb.state == VIDEOBUF_ERROR)
		return POLLIN|POLLRDNORM;
	return 0;
		rc =  POLLIN|POLLRDNORM;
	else
		rc = 0;
err:
	mutex_unlock(&fh->cap.vb_lock);
	return POLLERR;
	return rc;
}

static int bttv_open(struct file *file)
+10 −4
Original line number Diff line number Diff line
@@ -796,6 +796,7 @@ static unsigned int video_poll(struct file *file,
{
	struct cx23885_fh *fh = file->private_data;
	struct cx23885_buffer *buf;
	unsigned int rc = POLLERR;

	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
		if (!res_get(fh->dev, fh, RESOURCE_VBI))
@@ -803,23 +804,28 @@ static unsigned int video_poll(struct file *file,
		return videobuf_poll_stream(file, &fh->vbiq, wait);
	}

	mutex_lock(&fh->vidq.vb_lock);
	if (res_check(fh, RESOURCE_VIDEO)) {
		/* streaming capture */
		if (list_empty(&fh->vidq.stream))
			return POLLERR;
			goto done;
		buf = list_entry(fh->vidq.stream.next,
			struct cx23885_buffer, vb.stream);
	} else {
		/* read() capture */
		buf = (struct cx23885_buffer *)fh->vidq.read_buf;
		if (NULL == buf)
			return POLLERR;
			goto done;
	}
	poll_wait(file, &buf->vb.done, wait);
	if (buf->vb.state == VIDEOBUF_DONE ||
	    buf->vb.state == VIDEOBUF_ERROR)
		return POLLIN|POLLRDNORM;
	return 0;
		rc =  POLLIN|POLLRDNORM;
	else
		rc = 0;
done:
	mutex_unlock(&fh->vidq.vb_lock);
	return rc;
}

static int video_release(struct file *file)
+10 −4
Original line number Diff line number Diff line
@@ -869,6 +869,7 @@ video_poll(struct file *file, struct poll_table_struct *wait)
{
	struct cx8800_fh *fh = file->private_data;
	struct cx88_buffer *buf;
	unsigned int rc = POLLERR;

	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
		if (!res_get(fh->dev,fh,RESOURCE_VBI))
@@ -876,22 +877,27 @@ video_poll(struct file *file, struct poll_table_struct *wait)
		return videobuf_poll_stream(file, &fh->vbiq, wait);
	}

	mutex_lock(&fh->vidq.vb_lock);
	if (res_check(fh,RESOURCE_VIDEO)) {
		/* streaming capture */
		if (list_empty(&fh->vidq.stream))
			return POLLERR;
			goto done;
		buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
	} else {
		/* read() capture */
		buf = (struct cx88_buffer*)fh->vidq.read_buf;
		if (NULL == buf)
			return POLLERR;
			goto done;
	}
	poll_wait(file, &buf->vb.done, wait);
	if (buf->vb.state == VIDEOBUF_DONE ||
	    buf->vb.state == VIDEOBUF_ERROR)
		return POLLIN|POLLRDNORM;
	return 0;
		rc = POLLIN|POLLRDNORM;
	else
		rc = 0;
done:
	mutex_unlock(&fh->vidq.vb_lock);
	return rc;
}

static int video_release(struct file *file)