De-inline qt_ignore_sigpipe()

It contains a static guard variable, so every user of the function
outside of QtCore (at least QtNetwork contains one) will create its
own copy of the guard variable. While mostly harmless, we'd be
executing too many sigaction() calls this way.

As a drive-by, remove the qatomic.h include and replace the C-style
struct initialization (memset()) with C++-style
(value-)initialization.

I also tried C++20/C99 designated initializers, but they cannot be
used here: some platforms #define sa_handler to some nested member
accessor because they hold the field in a union. While .a.b is allowed
in C99, it isn't in C++20, so we'd have to move this function's
definition into a .c file to compile `{ .sa_handler = SIG_IGN }`.
That'd be too much hassle.

Mark the function as noexcept, because it is (sigaction(2) is not a
Posix Cancellation Point), and, now that it's out-of-line, that
actually matters to codegen.

Change-Id: Iffab9e6b57822a4d1be8b81ed5948ce186df978e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2023-11-07 19:05:33 +01:00
parent e795898cc4
commit 9bed675df8
2 changed files with 17 additions and 16 deletions

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qbasicatomic.h>
#include "qcore_unix_p.h"
#include <stdlib.h>
@ -19,6 +20,21 @@
QT_BEGIN_NAMESPACE
void qt_ignore_sigpipe() noexcept // noexcept: sigaction(2) is not a Posix Cancellation Point
{
// Set to ignore SIGPIPE once only.
Q_CONSTINIT static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
if (!atom.loadRelaxed()) {
// More than one thread could turn off SIGPIPE at the same time
// But that's acceptable because they all would be doing the same
// action
struct sigaction noaction = {};
noaction.sa_handler = SIG_IGN;
::sigaction(SIGPIPE, &noaction, nullptr);
atom.storeRelaxed(1);
}
}
QByteArray qt_readlink(const char *path)
{
#ifndef PATH_MAX

View File

@ -18,7 +18,6 @@
#include "qplatformdefs.h"
#include <QtCore/private/qglobal_p.h>
#include "qatomic.h"
#include "qbytearray.h"
#include "qdeadlinetimer.h"
@ -181,21 +180,7 @@ inline timespec qAbsTimespec(timespec ts)
return normalizedTimespec(ts);
}
inline void qt_ignore_sigpipe()
{
// Set to ignore SIGPIPE once only.
Q_CONSTINIT static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
if (!atom.loadRelaxed()) {
// More than one thread could turn off SIGPIPE at the same time
// But that's acceptable because they all would be doing the same
// action
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
::sigaction(SIGPIPE, &noaction, nullptr);
atom.storeRelaxed(1);
}
}
Q_CORE_EXPORT void qt_ignore_sigpipe() noexcept;
#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
# if !__GLIBC_PREREQ(2, 22)