diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-09-11 13:36:54 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-01-05 13:45:53 (GMT) |
commit | f31ff453c3f03ffae21ec9bcd64e9cd93547e6d2 (patch) | |
tree | d1ea50c22f491b81630281e6ea077026834d32d9 /src | |
parent | b36bf7507c02f0e3cf32abda49e295fdd94a4848 (diff) | |
download | Qt-f31ff453c3f03ffae21ec9bcd64e9cd93547e6d2.zip Qt-f31ff453c3f03ffae21ec9bcd64e9cd93547e6d2.tar.gz Qt-f31ff453c3f03ffae21ec9bcd64e9cd93547e6d2.tar.bz2 |
Fix thread-safety of qt_ignore_sigpipe
The testAndSet operation would mean another thread could see the value
of 1 and proceed to write(2)/sendto(2) before SIGPIPE had been ignored.
If the pipe or socket were already closed by then, a SIGPIPE would be
delivered to the application with its default action: terminate.
(cherry-picked from qtbase commit 3f970c20f9afd5c9a1cc14d7f69882e13f6aaf1b)
Change-Id: I62dc8f5fa14c1dd453d13e4053c642bd78fbc468
Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Reviewed-by: Peter Hartmann <phartmann@rim.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 6 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 6 |
2 files changed, 10 insertions, 2 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 82d80dc..2feb6a5 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -962,11 +962,15 @@ static void qt_ignore_sigpipe() { // Set to ignore SIGPIPE once only. static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); - if (atom.testAndSetRelaxed(0, 1)) { + if (!atom) { + // 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, 0); + atom = 1; } } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b4e5126..640a627 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -106,11 +106,15 @@ static void qt_ignore_sigpipe() #ifndef Q_NO_POSIX_SIGNALS // Set to ignore SIGPIPE once only. static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); - if (atom.testAndSetRelaxed(0, 1)) { + if (!atom) { + // 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, 0); + atom = 1; } #else // Posix signals are not supported by the underlying platform |