This is an automatic generated email to let you know that the following patch were queued at the http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:
Subject: v4l2-compliance: test polling and disconnecting Author: Hans Verkuil <[email protected]> Date: Wed Jan 6 09:21:53 2021 +0100 Test that disconnecting a device will wake up any processes that are using select or poll. This can only be tested with the vivid driver that enabled the DISCONNECT control. Signed-off-by: Hans Verkuil <[email protected]> utils/v4l2-compliance/v4l2-compliance.cpp | 8 +++ utils/v4l2-compliance/v4l2-compliance.h | 5 ++ utils/v4l2-compliance/v4l2-test-controls.cpp | 87 +++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 2 deletions(-) --- http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=4739a67dac10389559cffa6450a9ad88d37629ac diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index 2d4d10db1088..9e7b14c7ace8 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -1438,6 +1438,14 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ * S_SELECTION flags tests */ + if (is_vivid && + node.controls.find(VIVID_CID_DISCONNECT) != node.controls.end()) { + if (node.node2) + node.node2->close(); + node.node2 = NULL; + printf("\ttest Disconnect: %s\n\n", ok(testVividDisconnect(&node))); + } + restoreState(); show_total: diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 5cfe870b8b6e..c0cc57db153c 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -70,6 +70,10 @@ enum poll_mode { #define IS_ENCODER(node) ((node)->codec_mask & (JPEG_ENCODER | STATEFUL_ENCODER | STATELESS_ENCODER)) #define IS_DECODER(node) ((node)->codec_mask & (JPEG_DECODER | STATEFUL_DECODER | STATELESS_DECODER)) +#define V4L2_CTRL_CLASS_VIVID 0x00f00000 +#define VIVID_CID_VIVID_BASE (V4L2_CTRL_CLASS_VIVID | 0xf000) +#define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65) + struct test_query_ext_ctrl: v4l2_query_ext_ctrl { __u64 menu_mask; }; @@ -296,6 +300,7 @@ int testQueryControls(struct node *node); int testSimpleControls(struct node *node); int testExtendedControls(struct node *node); int testEvents(struct node *node); +int testVividDisconnect(struct node *node); int testJpegComp(struct node *node); // I/O configuration ioctl tests diff --git a/utils/v4l2-compliance/v4l2-test-controls.cpp b/utils/v4l2-compliance/v4l2-test-controls.cpp index 839132b6f9c1..9a68b7e847b0 100644 --- a/utils/v4l2-compliance/v4l2-test-controls.cpp +++ b/utils/v4l2-compliance/v4l2-test-controls.cpp @@ -23,12 +23,12 @@ #include <vector> #include <sys/types.h> +#include <sys/wait.h> +#include <sys/epoll.h> #include "compiler.h" #include "v4l2-compliance.h" -#define V4L2_CTRL_CLASS_VIVID 0x00f00000 - static int checkQCtrl(struct node *node, struct test_query_ext_ctrl &qctrl) { struct v4l2_querymenu qmenu; @@ -901,6 +901,89 @@ int testEvents(struct node *node) return 0; } +int testVividDisconnect(struct node *node) +{ + // Test that disconnecting a device will wake up any processes + // that are using select or poll. + // + // This can only be tested with the vivid driver that enabled + // the DISCONNECT control. + + pid_t pid = fork(); + if (pid == 0) { + struct timeval tv = { 5, 0 }; + fd_set fds; + + FD_ZERO(&fds); + FD_SET(node->g_fd(), &fds); + int res = select(node->g_fd() + 1, nullptr, nullptr, &fds, &tv); + // No POLLPRI seen + if (res != 1) + exit(1); + // POLLPRI seen, but didn't wake up + if (!tv.tv_sec) + exit(2); + v4l2_event ev = {}; + // Woke up on POLLPRI, but VIDIOC_DQEVENT didn't return + // the ENODEV error. + if (doioctl(node, VIDIOC_DQEVENT, &ev) != ENODEV) + exit(3); + exit(0); + } + v4l2_control ctrl = { VIVID_CID_DISCONNECT, 0 }; + sleep(1); + fail_on_test(doioctl(node, VIDIOC_S_CTRL, &ctrl)); + int wstatus; + fail_on_test(waitpid(pid, &wstatus, 0) != pid); + fail_on_test(!WIFEXITED(wstatus)); + if (WEXITSTATUS(wstatus)) + return fail("select child exited with status %d\n", WEXITSTATUS(wstatus)); + + node->reopen(); + + pid = fork(); + if (pid == 0) { + struct epoll_event ep_ev; + int epollfd = epoll_create1(0); + + if (epollfd < 0) + exit(1); + + ep_ev.events = 0; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, node->g_fd(), &ep_ev)) + exit(2); + + ep_ev.events = EPOLLPRI; + ep_ev.data.fd = node->g_fd(); + if (epoll_ctl(epollfd, EPOLL_CTL_MOD, node->g_fd(), &ep_ev)) + exit(3); + int ret = epoll_wait(epollfd, &ep_ev, 1, 5000); + if (ret == 0) + exit(4); + if (ret < 0) + exit(5); + if (ret != 1) + exit(6); + if (!(ep_ev.events & EPOLLPRI)) + exit(7); + if (!(ep_ev.events & EPOLLERR)) + exit(8); + v4l2_event ev = {}; + // Woke up on POLLPRI, but VIDIOC_DQEVENT didn't return + // the ENODEV error. + if (doioctl(node, VIDIOC_DQEVENT, &ev) != ENODEV) + exit(9); + exit(0); + } + sleep(1); + fail_on_test(doioctl(node, VIDIOC_S_CTRL, &ctrl)); + fail_on_test(waitpid(pid, &wstatus, 0) != pid); + fail_on_test(!WIFEXITED(wstatus)); + if (WEXITSTATUS(wstatus)) + return fail("epoll child exited with status %d\n", WEXITSTATUS(wstatus)); + return 0; +} + int testJpegComp(struct node *node) { struct v4l2_jpegcompression jc; _______________________________________________ linuxtv-commits mailing list [email protected] https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits
