Message ID | 20250424114103.451395-9-barnabas.pocze@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Quoting Barnabás Pőcze (2025-04-24 12:41:02) > Use the `close_range()` system call when available as it is simpler > and faster than iterating `/proc/self/fd/`. > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > meson.build | 4 ++++ > src/libcamera/process.cpp | 25 +++++++++++++++++++++++++ > 2 files changed, 29 insertions(+) > > diff --git a/meson.build b/meson.build > index 9ba5e2ca9..ae13727eb 100644 > --- a/meson.build > +++ b/meson.build > @@ -74,6 +74,10 @@ cc = meson.get_compiler('c') > cxx = meson.get_compiler('cpp') > config_h = configuration_data() > > +if cc.has_header_symbol('unistd.h', 'close_range', prefix : '#define _GNU_SOURCE') > + config_h.set('HAVE_CLOSE_RANGE', 1) > +endif > + > if cc.has_header_symbol('fcntl.h', 'F_ADD_SEALS', prefix : '#define _GNU_SOURCE') > config_h.set('HAVE_FILE_SEALS', 1) > endif > diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp > index 369fdb12d..42b56374d 100644 > --- a/src/libcamera/process.cpp > +++ b/src/libcamera/process.cpp > @@ -70,6 +70,31 @@ void closeAllFdsExcept(Span<const int> fds) > > ASSERT(v.empty() || v.front() >= 0); > > +#if HAVE_CLOSE_RANGE > + /* > + * At the moment libcamera does not require at least Linux 5.9, > + * which introduced the `close_range()` system call, so a runtime > + * check is also needed to make sure that it is supported. > + */ > + static const bool hasCloseRange = [] { > + return close_range(~0u, 0, 0) < 0 && errno == EINVAL; > + }(); > + > + if (hasCloseRange) { > + unsigned int prev = 0; > + > + for (unsigned int curr : v) { > + ASSERT(prev <= curr + 1); > + if (prev < curr) > + close_range(prev, curr - 1, 0); > + prev = curr + 1; Aha, I see it now. I was lost thinking this patch was a change in behaviour - but it looks sane to me. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > + } > + > + close_range(prev, ~0u, 0); > + return; > + } > +#endif > + > DIR *dir = opendir("/proc/self/fd"); > if (!dir) > return; > -- > 2.49.0 >
diff --git a/meson.build b/meson.build index 9ba5e2ca9..ae13727eb 100644 --- a/meson.build +++ b/meson.build @@ -74,6 +74,10 @@ cc = meson.get_compiler('c') cxx = meson.get_compiler('cpp') config_h = configuration_data() +if cc.has_header_symbol('unistd.h', 'close_range', prefix : '#define _GNU_SOURCE') + config_h.set('HAVE_CLOSE_RANGE', 1) +endif + if cc.has_header_symbol('fcntl.h', 'F_ADD_SEALS', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_FILE_SEALS', 1) endif diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp index 369fdb12d..42b56374d 100644 --- a/src/libcamera/process.cpp +++ b/src/libcamera/process.cpp @@ -70,6 +70,31 @@ void closeAllFdsExcept(Span<const int> fds) ASSERT(v.empty() || v.front() >= 0); +#if HAVE_CLOSE_RANGE + /* + * At the moment libcamera does not require at least Linux 5.9, + * which introduced the `close_range()` system call, so a runtime + * check is also needed to make sure that it is supported. + */ + static const bool hasCloseRange = [] { + return close_range(~0u, 0, 0) < 0 && errno == EINVAL; + }(); + + if (hasCloseRange) { + unsigned int prev = 0; + + for (unsigned int curr : v) { + ASSERT(prev <= curr + 1); + if (prev < curr) + close_range(prev, curr - 1, 0); + prev = curr + 1; + } + + close_range(prev, ~0u, 0); + return; + } +#endif + DIR *dir = opendir("/proc/self/fd"); if (!dir) return;