1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
From: Gabriele Svelto <gsvelto@mozilla.com>
Date: Mon, 28 Oct 2019 23:26:00 +0000
Subject: Bug 1590984 - Use poll() instead of select() in WebRTC code r=drno
The use of select() was leading to crashes when the file descriptor value was
larger than FD_SETSIZE. Recent versions of glibc have checks in the FD_CLR(),
FD_SET() and FD_ISSET() macros that will abort() the program instead of doing
an out-of-bounds access. poll() doesn't have limitations on the file
descriptor values and provides behavior that is otherwise identical to
select() thus solving the problem.
Differential Revision: https://phabricator.services.mozilla.com/D50798
Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/59fb6760bb6785a6f8a51be6fc66bf04cfba3e16
---
.../video_capture/linux/device_info_linux.cc | 1 +
.../video_capture/linux/device_info_v4l2.cc | 16 +++++-----
.../linux/video_capture_linux.cc | 1 +
.../video_capture/linux/video_capture_v4l2.cc | 29 +++++++++++--------
4 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/modules/video_capture/linux/device_info_linux.cc b/modules/video_capture/linux/device_info_linux.cc
index 56da475bf3..cae63c7c2d 100644
--- a/modules/video_capture/linux/device_info_linux.cc
+++ b/modules/video_capture/linux/device_info_linux.cc
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc
index f77d791033..a2435bcd4f 100644
--- a/modules/video_capture/linux/device_info_v4l2.cc
+++ b/modules/video_capture/linux/device_info_v4l2.cc
@@ -12,6 +12,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -91,16 +92,13 @@ void DeviceInfoV4l2::HandleEvent(inotify_event* event, int fd)
int DeviceInfoV4l2::EventCheck(int fd)
{
- struct timeval timeout;
- fd_set rfds;
+ struct pollfd fds = {
+ .fd = fd,
+ .events = POLLIN,
+ .revents = 0
+ };
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
-
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
-
- return select(fd+1, &rfds, NULL, NULL, &timeout);
+ return poll(&fds, 1, 100);
}
int DeviceInfoV4l2::HandleEvents(int fd)
diff --git a/modules/video_capture/linux/video_capture_linux.cc b/modules/video_capture/linux/video_capture_linux.cc
index 23a8f4f3f3..b2c206d775 100644
--- a/modules/video_capture/linux/video_capture_linux.cc
+++ b/modules/video_capture/linux/video_capture_linux.cc
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc
index 7a70c2ff88..00cede01cb 100644
--- a/modules/video_capture/linux/video_capture_v4l2.cc
+++ b/modules/video_capture/linux/video_capture_v4l2.cc
@@ -12,7 +12,7 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/videodev2.h>
+#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
@@ -20,6 +20,14 @@
#include <sys/select.h>
#include <time.h>
#include <unistd.h>
+// v4l includes
+#if defined(__NetBSD__) || defined(__OpenBSD__) // WEBRTC_BSD
+#include <sys/videoio.h>
+#elif defined(__sun)
+#include <sys/videodev2.h>
+#else
+#include <linux/videodev2.h>
+#endif
#include <new>
#include <string>
@@ -405,16 +413,13 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
int retVal = 0;
- fd_set rSet;
- struct timeval timeout;
+ struct pollfd rSet;
- FD_ZERO(&rSet);
- FD_SET(_deviceFd, &rSet);
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ rSet.fd = _deviceFd;
+ rSet.events = POLLIN;
+ rSet.revents = 0;
- // _deviceFd written only in StartCapture, when this thread isn't running.
- retVal = select(_deviceFd + 1, &rSet, NULL, NULL, &timeout);
+ retVal = poll(&rSet, 1, 1000);
{
MutexLock lock(&capture_lock_);
@@ -424,12 +429,12 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
}
if (retVal < 0 && errno != EINTR) { // continue if interrupted
- // select failed
+ // poll failed
return false;
} else if (retVal == 0) {
- // select timed out
+ // poll timed out
return true;
- } else if (!FD_ISSET(_deviceFd, &rSet)) {
+ } else if (!(rSet.revents & POLLIN)) {
// not event on camera handle
return true;
}
|