diff --git a/plugins/linux-v4l2/v4l2-udev.c b/plugins/linux-v4l2/v4l2-udev.c
index 8394b6276..67a50af86 100644
--- a/plugins/linux-v4l2/v4l2-udev.c
+++ b/plugins/linux-v4l2/v4l2-udev.c
@@ -15,6 +15,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+#include
+#include
+#include
#include
#include
@@ -40,6 +43,7 @@ static pthread_mutex_t udev_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t udev_thread;
static os_event_t *udev_event;
+static int udev_event_fd;
static signal_handler_t *udev_signalhandler = NULL;
@@ -108,8 +112,6 @@ static void *udev_event_thread(void *vptr)
UNUSED_PARAMETER(vptr);
int fd;
- fd_set fds;
- struct timeval tv;
struct udev *udev;
struct udev_monitor *mon;
struct udev_device *dev;
@@ -127,12 +129,14 @@ static void *udev_event_thread(void *vptr)
fd = udev_monitor_get_fd(mon);
while (os_event_try(udev_event) == EAGAIN) {
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- tv.tv_sec = 1;
- tv.tv_usec = 0;
+ struct pollfd fds[2];
- if (select(fd + 1, &fds, NULL, NULL, &tv) <= 0)
+ fds[0].fd = fd;
+ fds[0].events = POLLIN;
+ fds[1].fd = udev_event_fd;
+ fds[1].events = POLLIN;
+
+ if (poll(fds, 2, 1000) <= 0)
continue;
dev = udev_monitor_receive_device(mon);
@@ -158,13 +162,19 @@ void v4l2_init_udev(void)
if (udev_refs == 0) {
if (os_event_init(&udev_event, OS_EVENT_TYPE_MANUAL) != 0)
goto fail;
- if (pthread_create(&udev_thread, NULL, udev_event_thread,
- NULL) != 0)
+ if ((udev_event_fd = eventfd(0, EFD_CLOEXEC)) < 0)
goto fail;
+ if (pthread_create(&udev_thread, NULL, udev_event_thread,
+ NULL) != 0) {
+ close(udev_event_fd);
+ goto fail;
+ }
udev_signalhandler = signal_handler_create();
- if (!udev_signalhandler)
+ if (!udev_signalhandler) {
+ close(udev_event_fd);
goto fail;
+ }
signal_handler_add_array(udev_signalhandler, udev_signals);
}
udev_refs++;
@@ -180,8 +190,10 @@ void v4l2_unref_udev(void)
/* unref udev monitor */
if (udev_refs && --udev_refs == 0) {
os_event_signal(udev_event);
+ eventfd_write(udev_event_fd, 1);
pthread_join(udev_thread, NULL);
os_event_destroy(udev_event);
+ close(udev_event_fd);
if (udev_signalhandler)
signal_handler_destroy(udev_signalhandler);