int sync_wait(int fd, int timeout)
{
struct pollfd fds;
int ret;
if (fd < 0) {
errno = EINVAL;
return -1;
}
fds.fd = fd;
fds.events = POLLIN;
do {
ret = poll(&fds, 1, timeout);
if (ret > 0) {
if (fds.revents & (POLLERR | POLLNVAL)) {
errno = EINVAL;
return -1;
}
return 0;
} else if (ret == 0) {
errno = ETIME;
return -1;
}
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
return ret;
}
poll调用到驱动实现的字符设备poll接口
static const struct v4l2_file_operations video_file_ops = {
.owner = THIS_MODULE,
.unlocked_ioctl = video_ioctl2,
.open = video_open,
.release = video_release,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
.read = vb2_fop_read,
};
vb2_fop_poll
--vb2_poll
----vb2_core_poll
------poll_wait
if (list_empty(&q->done_list)) {
/*
* If the last buffer was dequeued from a capture queue,
* return immediately. DQBUF will return -EPIPE.
*/
if (q->last_buffer_dequeued)
return POLLIN | POLLRDNORM;
poll_wait(file, &q->done_wq, wait);
}
等待q->done_wq唤醒
vb2_buffer_done
--
switch (state) {
case VB2_BUF_STATE_QUEUED:
return;
case VB2_BUF_STATE_REQUEUEING:
if (q->start_streaming_called)
__enqueue_in_driver(vb);
return;
default:
/* Inform any processes that may be waiting for buffers */
wake_up(&q->done_wq);
break;
}
--
实现的驱动会调用vb2_buffer_done,唤醒q->done_wq的等待队列,此时应用即可DQBUF。
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点