1 From: Gabriele Svelto <gsvelto@mozilla.com>
2 Date: Mon, 28 Oct 2019 23:26:00 +0000
3 Subject: Bug 1590984 - Use poll() instead of select() in WebRTC code r=drno
5 The use of select() was leading to crashes when the file descriptor value was
6 larger than FD_SETSIZE. Recent versions of glibc have checks in the FD_CLR(),
7 FD_SET() and FD_ISSET() macros that will abort() the program instead of doing
8 an out-of-bounds access. poll() doesn't have limitations on the file
9 descriptor values and provides behavior that is otherwise identical to
10 select() thus solving the problem.
12 Differential Revision: https://phabricator.services.mozilla.com/D50798
13 Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/59fb6760bb6785a6f8a51be6fc66bf04cfba3e16
15 .../video_capture/linux/device_info_linux.cc | 1 +
16 .../video_capture/linux/device_info_v4l2.cc | 16 +++++-----
17 .../linux/video_capture_linux.cc | 1 +
18 .../video_capture/linux/video_capture_v4l2.cc | 29 +++++++++++--------
19 4 files changed, 26 insertions(+), 21 deletions(-)
21 diff --git a/modules/video_capture/linux/device_info_linux.cc b/modules/video_capture/linux/device_info_linux.cc
22 index 56da475bf3..cae63c7c2d 100644
23 --- a/modules/video_capture/linux/device_info_linux.cc
24 +++ b/modules/video_capture/linux/device_info_linux.cc
33 diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc
34 index f77d791033..a2435bcd4f 100644
35 --- a/modules/video_capture/linux/device_info_v4l2.cc
36 +++ b/modules/video_capture/linux/device_info_v4l2.cc
45 @@ -91,16 +92,13 @@ void DeviceInfoV4l2::HandleEvent(inotify_event* event, int fd)
47 int DeviceInfoV4l2::EventCheck(int fd)
49 - struct timeval timeout;
51 + struct pollfd fds = {
58 - timeout.tv_usec = 100000;
63 - return select(fd+1, &rfds, NULL, NULL, &timeout);
64 + return poll(&fds, 1, 100);
67 int DeviceInfoV4l2::HandleEvents(int fd)
68 diff --git a/modules/video_capture/linux/video_capture_linux.cc b/modules/video_capture/linux/video_capture_linux.cc
69 index 23a8f4f3f3..b2c206d775 100644
70 --- a/modules/video_capture/linux/video_capture_linux.cc
71 +++ b/modules/video_capture/linux/video_capture_linux.cc
79 #include <sys/ioctl.h>
80 diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc
81 index 7a70c2ff88..00cede01cb 100644
82 --- a/modules/video_capture/linux/video_capture_v4l2.cc
83 +++ b/modules/video_capture/linux/video_capture_v4l2.cc
88 -#include <linux/videodev2.h>
92 #include <sys/ioctl.h>
94 #include <sys/select.h>
98 +#if defined(__NetBSD__) || defined(__OpenBSD__) // WEBRTC_BSD
99 +#include <sys/videoio.h>
100 +#elif defined(__sun)
101 +#include <sys/videodev2.h>
103 +#include <linux/videodev2.h>
108 @@ -405,16 +413,13 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
109 RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
113 - struct timeval timeout;
114 + struct pollfd rSet;
117 - FD_SET(_deviceFd, &rSet);
118 - timeout.tv_sec = 1;
119 - timeout.tv_usec = 0;
120 + rSet.fd = _deviceFd;
121 + rSet.events = POLLIN;
124 - // _deviceFd written only in StartCapture, when this thread isn't running.
125 - retVal = select(_deviceFd + 1, &rSet, NULL, NULL, &timeout);
126 + retVal = poll(&rSet, 1, 1000);
129 MutexLock lock(&capture_lock_);
130 @@ -424,12 +429,12 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
133 if (retVal < 0 && errno != EINTR) { // continue if interrupted
137 } else if (retVal == 0) {
138 - // select timed out
141 - } else if (!FD_ISSET(_deviceFd, &rSet)) {
142 + } else if (!(rSet.revents & POLLIN)) {
143 // not event on camera handle